233 prev next chunks index CyanogenMod/android_packages_apps_Trebuchet_22633476f76182e10641362b5632bf5d27bd6e82_src/com/android/launcher3/Launcher.java {strict: [[bj]], subset: [[bj]]}
line based (standard git) jfstmerge spork
   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16                                                                                                          
  17 package com.android.launcher3;                                                                           
  18                                                                                                          
  19 import android.animation.Animator;                                                                       
  20 import android.animation.AnimatorListenerAdapter;                                                        
  21 import android.animation.AnimatorSet;                                                                    
  22 import android.animation.ObjectAnimator;                                                                 
  23 import android.animation.PropertyValuesHolder;                                                           
  24 import android.animation.ValueAnimator;                                                                  
  25 import android.annotation.TargetApi;                                                                     
  26 import android.app.Activity;                                                                             
  27 import android.app.ActivityManager;                                                                      
  28 import android.app.ActivityOptions;                                                                      
  29 import android.app.AlertDialog;                                                                          
  30 import android.app.SearchManager;                                                                        
  31 import android.appwidget.AppWidgetHostView;                                                              
  32 import android.appwidget.AppWidgetManager;                                                               
  33 import android.appwidget.AppWidgetProviderInfo;                                                          
  34 import android.content.ActivityNotFoundException;                                                        
  35 import android.content.BroadcastReceiver;                                                                
  36 import android.content.ComponentCallbacks2;                                                              
  37 import android.content.ComponentName;                                                                    
  38 import android.content.ContentResolver;                                                                  
  39 import android.content.Context;                                                                          
  40 import android.content.DialogInterface;                                                                  
  41 import android.content.Intent;                                                                           
  42 import android.content.IntentFilter;                                                                     
  43 import android.content.IntentSender;                                                                     
  44 import android.content.SharedPreferences;                                                                
  45 import android.content.pm.ActivityInfo;                                                                  
  46 import android.content.pm.ApplicationInfo;                                                               
  47 import android.content.pm.PackageManager;                                                                
  48 import android.content.pm.PackageManager.NameNotFoundException;                                          
  49 import android.content.res.Configuration;                                                                
  50 import android.database.ContentObserver;                                                                 
  51 import android.database.sqlite.SQLiteDatabase;                                                           
  52 import android.graphics.Bitmap;                                                                          
  53 import android.graphics.Canvas;                                                                          
  54 import android.graphics.Color;                                                                           
  55 import android.graphics.PorterDuff;                                                                      
  56 import android.graphics.Rect;                                                                            
  57 import android.graphics.drawable.Drawable;                                                               
  58 import android.net.Uri;                                                                                  
  59 import android.os.AsyncTask;                                                                             
  60 import android.os.Build;                                                                                 
  61 import android.os.Bundle;                                                                                
  62 import android.os.Environment;                                                                           
  63 import android.os.Handler;                                                                               
  64 import android.os.Message;                                                                               
  65 import android.os.StrictMode;                                                                            
  66 import android.os.SystemClock;                                                                           
  67 import android.text.Selection;                                                                           
  68 import android.text.SpannableStringBuilder;                                                              
  69 import android.text.TextUtils;                                                                           
  70 import android.text.method.TextKeyListener;                                                              
  71 import android.util.Log;                                                                                 
  72 import android.view.Display;                                                                             
  73 import android.view.Gravity;                                                                             
  74 import android.view.HapticFeedbackConstants;                                                             
  75 import android.view.KeyEvent;                                                                            
  76 import android.view.LayoutInflater;                                                                      
  77 import android.view.Menu;                                                                                
  78 import android.view.MotionEvent;                                                                         
  79 import android.view.Surface;                                                                             
  80 import android.view.View;                                                                                
  81 import android.view.View.OnClickListener;                                                                
  82 import android.view.View.OnLongClickListener;                                                            
  83 import android.view.ViewGroup;                                                                           
  84 import android.view.ViewStub;                                                                            
  85 import android.view.ViewTreeObserver;                                                                    
  86 import android.view.Window;                                                                              
  87 import android.view.WindowManager;                                                                       
  88 import android.view.accessibility.AccessibilityEvent;                                                    
  89 import android.view.inputmethod.InputMethodManager;                                                      
  90 import android.widget.Advanceable;                                                                       
  91 import android.widget.FrameLayout;                                                                       
  92 import android.widget.ImageView;                                                                         
  93 import android.widget.TextView;                                                                          
  94 import android.widget.Toast;                                                                             
  95                                                                                                          
  96 import com.android.launcher3.DropTarget.DragObject;                                                      
  97 import com.android.launcher3.PagedView.PageSwitchListener;                                               
  98 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
  99 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 100 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 101 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 102 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 103 import com.android.launcher3.compat.UserHandleCompat;                                                    
 104 import com.android.launcher3.compat.UserManagerCompat;                                                   
 105 import com.android.launcher3.util.Thunk;                                                                 
 106 import com.android.launcher3.widget.PendingAddWidgetInfo;                                                
 107 import com.android.launcher3.widget.WidgetsContainerView;                                                
 108                                                                                                          
 109 import java.io.DataInputStream;                                                                          
 110 import java.io.DataOutputStream;                                                                         
 111 import java.io.File;                                                                                     
 112 import java.io.FileDescriptor;                                                                           
 113 import java.io.FileNotFoundException;                                                                    
 114 import java.io.FileOutputStream;                                                                         
 115 import java.io.IOException;                                                                              
 116 import java.io.PrintWriter;                                                                              
 117 import java.lang.reflect.InvocationTargetException;                                                      
 118 import java.lang.reflect.Method;                                                                         
 119 import java.text.DateFormat;                                                                             
 120 import java.util.ArrayList;                                                                              
 121 import java.util.Collection;                                                                             
 122 import java.util.Date;                                                                                   
 123 import java.util.HashMap;                                                                                
 124 import java.util.HashSet;                                                                                
 125 import java.util.List;                                                                                   
 126 import java.util.concurrent.atomic.AtomicInteger;                                                        
 127                                                                                                          
 128 /**                                                                                                      
 129  * Default launcher application.                                                                         
 130  */                                                                                                      
 131 public class Launcher extends Activity                                                                   
 132         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 133                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,             
 134                    LauncherStateTransitionAnimation.Callbacks {                                          
 135     static final String TAG = "Launcher";                                                                
 136     static final boolean LOGD = true;                                                                    
 137                                                                                                          
 138     static final boolean PROFILE_STARTUP = false;                                                        
 139     static final boolean DEBUG_WIDGETS = true;                                                           
 140     static final boolean DEBUG_STRICT_MODE = false;                                                      
 141     static final boolean DEBUG_RESUME_TIME = false;                                                      
 142     static final boolean DEBUG_DUMP_LOG = false;                                                         
 143                                                                                                          
 144     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 145                                                                                                          
 146     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 147     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 148     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 149     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 150                                                                                                          
 151     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 152     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 153                                                                                                          
 154     /**                                                                                                  
 155      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 156      * request codes used internally.                                                                    
 157      */                                                                                                  
 158     protected static final int REQUEST_LAST = 100;                                                       
 159                                                                                                          
 160     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 161                                                                                                          
 162     static final int SCREEN_COUNT = 5;                                                                   
 163                                                                                                          
 164     // To turn on these properties, type                                                                 
 165     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 166     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 167                                                                                                          
 168     // The Intent extra that defines whether to ignore the launch animation                              
 169     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 170             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 171                                                                                                          
 172     // Type: int                                                                                         
 173     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 174     // Type: int                                                                                         
 175     private static final String RUNTIME_STATE = "launcher.state";                                        
 176     // Type: int                                                                                         
 177     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 178     // Type: int                                                                                         
 179     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 180     // Type: int                                                                                         
 181     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 182     // Type: int                                                                                         
 183     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 184     // Type: boolean                                                                                     
 185     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 186     // Type: long                                                                                        
 187     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 188     // Type: int                                                                                         
 189     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 190     // Type: int                                                                                         
 191     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 192     // Type: parcelable                                                                                  
 193     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 194     // Type: parcelable                                                                                  
 195     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 196     // Type: int[]                                                                                       
 197     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 198                                                                                                          
 199     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 200     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 201                                                                                                          
 202     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 203     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 204             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 205                                                                                                          
 206     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 207     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 208                                                                                                          
 209     private static final String QSB_WIDGET_ID = "qsb_widget_id";                                         
 210     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                             
 211                                                                                                          
 212     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 213                                                                                                          
 214     /** The different states that Launcher can be in. */                                                 
 215     enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED };            
 216     @Thunk State mState = State.WORKSPACE;                                                               
 217     @Thunk AnimatorSet mStateAnimation;                                                                  
 218     @Thunk LauncherStateTransitionAnimation mStateTransitionAnimation;                                   
 219                                                                                                          
 220     private boolean mIsSafeModeEnabled;                                                                  
 221                                                                                                          
 222     LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();             
 223     LauncherOverlay mLauncherOverlay;                                                                    
 224     InsettableFrameLayout mLauncherOverlayContainer;                                                     
 225                                                                                                          
 226     static final int APPWIDGET_HOST_ID = 1024;                                                           
 227     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 228     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 229     private static final int ACTIVITY_START_DELAY = 1000;                                                
 230                                                                                                          
 231     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 232     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 233                                                                                                          
 234     // How long to wait before the new-shortcut animation automatically pans the workspace               
 235     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 236     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 237     @Thunk static int NEW_APPS_ANIMATION_DELAY = 500;                                                    
 238                                                                                                          
 239     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 240             = new CloseSystemDialogsIntentReceiver();                                                    
 241     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 242                                                                                                          
 243     private LayoutInflater mInflater;                                                                    
 244                                                                                                          
 245     @Thunk Workspace mWorkspace;                                                                         
 246     private View mLauncherView;                                                                          
 247     private View mPageIndicators;                                                                        
 248     @Thunk DragLayer mDragLayer;                                                                         
 249     private DragController mDragController;                                                              
 250     private View mWeightWatcher;                                                                         
 251                                                                                                          
 252     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 253     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 254                                                                                                          
 255     @Thunk ItemInfo mPendingAddInfo = new ItemInfo();                                                    
 256     private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                         
 257     private int mPendingAddWidgetId = -1;                                                                
 258                                                                                                          
 259     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 260                                                                                                          
 261     private FolderInfo mFolderInfo;                                                                      
 262                                                                                                          
 263     private Hotseat mHotseat;                                                                            
 264     private ViewGroup mOverviewPanel;                                                                    
 265                                                                                                          
 266     private View mAllAppsButton;                                                                         
 267                                                                                                          
 268     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 269                                                                                                          
 270     // Main container view for the all apps screen.                                                      
 271     @Thunk AppsContainerView mAppsView;                                                                  
 272                                                                                                          
 273     // Main container view for the widget tray screen.                                                   
 274     private WidgetsContainerView mWidgetsView;                                                           
 275                                                                                                          
 276     private boolean mAutoAdvanceRunning = false;                                                         
 277     private AppWidgetHostView mQsb;                                                                      
 278                                                                                                          
 279     private Bundle mSavedState;                                                                          
 280     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 281     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 282     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 283     private State mOnResumeState = State.NONE;                                                           
 284                                                                                                          
 285     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 286                                                                                                          
 287     @Thunk boolean mWorkspaceLoading = true;                                                             
 288                                                                                                          
 289     private boolean mPaused = true;                                                                      
 290     private boolean mRestoring;                                                                          
 291     private boolean mWaitingForResult;                                                                   
 292     private boolean mOnResumeNeedsLoad;                                                                  
 293                                                                                                          
 294     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 295     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 296                                                                                                          
 297     private Bundle mSavedInstanceState;                                                                  
 298                                                                                                          
 299     private LauncherModel mModel;                                                                        
 300     private IconCache mIconCache;                                                                        
 301     @Thunk boolean mUserPresent = true;                                                                  
 302     private boolean mVisible = false;                                                                    
 303     private boolean mHasFocus = false;                                                                   
 304     private boolean mAttached = false;                                                                   
 305                                                                                                          
 306     @Thunk static LocaleConfiguration sLocaleConfiguration = null;                                       
 307                                                                                                          
 308     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 309                                                                                                          
 310     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 311                                                                                                          
 312     // Related to the auto-advancing of widgets                                                          
 313     private final int ADVANCE_MSG = 1;                                                                   
 314     private final int mAdvanceInterval = 20000;                                                          
 315     private final int mAdvanceStagger = 250;                                                             
 316     private long mAutoAdvanceSentTime;                                                                   
 317     private long mAutoAdvanceTimeLeft = -1;                                                              
 318     @Thunk HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                      
 319         new HashMap<View, AppWidgetProviderInfo>();                                                      
 320                                                                                                          
 321     // Determines how long to wait after a rotation before restoring the screen orientation to           
 322     // match the sensor state.                                                                           
 323     private final int mRestoreScreenOrientationDelay = 500;                                              
 324                                                                                                          
 325     @Thunk Drawable mWorkspaceBackgroundDrawable;                                                        
 326                                                                                                          
 327     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 328     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 329                                                                                                          
 330     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 331     static Date sDateStamp = new Date();                                                                 
 332     static DateFormat sDateFormat =                                                                      
 333             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 334     static long sRunStart = System.currentTimeMillis();                                                  
 335     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 336                                                                                                          
 337     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 338     // it from the context.                                                                              
 339     private SharedPreferences mSharedPrefs;                                                              
 340                                                                                                          
 341     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 342     // when we scroll to that page on resume.                                                            
 343     @Thunk ImageView mFolderIconImageView;                                                               
 344     private Bitmap mFolderIconBitmap;                                                                    
 345     private Canvas mFolderIconCanvas;                                                                    
 346     private Rect mRectForFolderAnimation = new Rect();                                                   
 347                                                                                                          
 348     private BubbleTextView mWaitingForResume;                                                            
 349                                                                                                          
 350     protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                
 351             new HashMap<String, CustomAppWidget>();                                                      
 352                                                                                                          
 353     private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                      
 354     static {                                                                                             
 355         if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                 
 356             sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                       
 357         }                                                                                                
 358     }                                                                                                    
 359                                                                                                          
 360     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 361     private static Method sClipRevealMethod = null;                                                      
 362     static {                                                                                             
 363         Class<?> activityOptionsClass = ActivityOptions.class;                                           
 364         try {                                                                                            
 365             sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",        
 366                     View.class, int.class, int.class, int.class, int.class);                             
 367         } catch (Exception e) {                                                                          
 368             // Earlier version                                                                           
 369         }                                                                                                
 370     }                                                                                                    
 371                                                                                                          
 372     @Thunk Runnable mBuildLayersRunnable = new Runnable() {                                              
 373         public void run() {                                                                              
 374             if (mWorkspace != null) {                                                                    
 375                 mWorkspace.buildPageHardwareLayers();                                                    
 376             }                                                                                            
 377         }                                                                                                
 378     };                                                                                                   
 379                                                                                                          
 380     private static PendingAddArguments sPendingAddItem;                                                  
 381                                                                                                          
 382     @Thunk static class PendingAddArguments {                                                            
 383         int requestCode;                                                                                 
 384         Intent intent;                                                                                   
 385         long container;                                                                                  
 386         long screenId;                                                                                   
 387         int cellX;                                                                                       
 388         int cellY;                                                                                       
 389         int appWidgetId;                                                                                 
 390     }                                                                                                    
 391                                                                                                          
 392     private Stats mStats;                                                                                
 393                                                                                                          
 394     FocusIndicatorView mFocusHandler;                                                                    
 395                                                                                                          
 396     @Override                                                                                            
 397     protected void onCreate(Bundle savedInstanceState) {                                                 
 398         if (DEBUG_STRICT_MODE) {                                                                         
 399             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 400                     .detectDiskReads()                                                                   
 401                     .detectDiskWrites()                                                                  
 402                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 403                     .penaltyLog()                                                                        
 404                     .build());                                                                           
 405             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 406                     .detectLeakedSqlLiteObjects()                                                        
 407                     .detectLeakedClosableObjects()                                                       
 408                     .penaltyLog()                                                                        
 409                     .penaltyDeath()                                                                      
 410                     .build());                                                                           
 411         }                                                                                                
 412                                                                                                          
 413         if (mLauncherCallbacks != null) {                                                                
 414             mLauncherCallbacks.preOnCreate();                                                            
 415         }                                                                                                
 416                                                                                                          
 417         super.onCreate(savedInstanceState);                                                              
 418                                                                                                          
 419         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 420         LauncherAppState app = LauncherAppState.getInstance();                                           
 421         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 422                                                                                                          
 423         // Lazy-initialize the dynamic grid                                                              
 424         DeviceProfile grid = app.initDynamicGrid(this);                                                  
 425                                                                                                          
 426         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 427         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 428                 Context.MODE_PRIVATE);                                                                   
 429         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 430         mModel = app.setLauncher(this);                                                                  
 431         mIconCache = app.getIconCache();                                                                 
 432         mIconCache.flushInvalidIcons(grid);                                                              
 433         mDragController = new DragController(this);                                                      
 434         mInflater = getLayoutInflater();                                                                 
 435         mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                    
 436                                                                                                          
 437         mStats = new Stats(this);                                                                        
 438                                                                                                          
 439         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 440                                                                                                          
 441         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 442         mAppWidgetHost.startListening();                                                                 
 443                                                                                                          
 444         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 445         // this also ensures that any synchronous binding below doesn't re-trigger another               
 446         // LauncherModel load.                                                                           
 447         mPaused = false;                                                                                 
 448                                                                                                          
 449         if (PROFILE_STARTUP) {                                                                           
 450             android.os.Debug.startMethodTracing(                                                         
 451                     Environment.getExternalStorageDirectory() + "/launcher");                            
 452         }                                                                                                
 453                                                                                                          
 454         checkForLocaleChange();                                                                          
 455         setContentView(R.layout.launcher);                                                               
 456                                                                                                          
 457         setupViews();                                                                                    
 458         grid.layout(this);                                                                               
 459                                                                                                          
 460         registerContentObservers();                                                                      
 461                                                                                                          
 462         lockAllApps();                                                                                   
 463                                                                                                          
 464         mSavedState = savedInstanceState;                                                                
 465         restoreState(mSavedState);                                                                       
 466                                                                                                          
 467         if (PROFILE_STARTUP) {                                                                           
 468             android.os.Debug.stopMethodTracing();                                                        
 469         }                                                                                                
 470                                                                                                          
 471         if (!mRestoring) {                                                                               
 472             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 473                 // If the user leaves launcher, then we should just load items asynchronously when       
 474                 // they return.                                                                          
 475                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 476             } else {                                                                                     
 477                 // We only load the page synchronously if the user rotates (or triggers a                
 478                 // configuration change) while launcher is in the foreground                             
 479                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 480             }                                                                                            
 481         }                                                                                                
 482                                                                                                          
 483         // For handling default keys                                                                     
 484         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 485         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 486                                                                                                          
 487         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 488         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 489                                                                                                          
 490         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 491         unlockScreenOrientation(true);                                                                   
 492                                                                                                          
 493         if (mLauncherCallbacks != null) {                                                                
 494             mLauncherCallbacks.onCreate(savedInstanceState);                                             
 495             if (mLauncherCallbacks.hasLauncherOverlay()) {                                               
 496                 ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                     
 497                 mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                      
 498                 mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                            
 499                         mLauncherOverlayContainer, mLauncherOverlayCallbacks);                           
 500                 mWorkspace.setLauncherOverlay(mLauncherOverlay);                                         
 501             }                                                                                            
 502         }                                                                                                
 503                                                                                                          
 504         if (shouldShowIntroScreen()) {                                                                   
 505             showIntroScreen();                                                                           
 506         } else {                                                                                         
 507             showFirstRunActivity();                                                                      
 508             showFirstRunClings();                                                                        
 509         }                                                                                                
 510     }                                                                                                    
 511                                                                                                          
 512     private LauncherCallbacks mLauncherCallbacks;                                                        
 513                                                                                                          
 514     public void onPostCreate(Bundle savedInstanceState) {                                                
 515         super.onPostCreate(savedInstanceState);                                                          
 516         if (mLauncherCallbacks != null) {                                                                
 517             mLauncherCallbacks.onPostCreate(savedInstanceState);                                         
 518         }                                                                                                
 519     }                                                                                                    
 520                                                                                                          
 521     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                   
 522         mLauncherCallbacks = callbacks;                                                                  
 523         mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {                
 524             @Override                                                                                    
 525             public void onAllAppsBoundsChanged(Rect bounds) {                                            
 526                 mAppsView.setFixedBounds(Launcher.this, bounds);                                         
 527             }                                                                                            
 528                                                                                                          
 529             @Override                                                                                    
 530             public void dismissAllApps() {                                                               
 531                 showWorkspace(true);                                                                     
 532             }                                                                                            
 533         });                                                                                              
 534         return true;                                                                                     
 535     }                                                                                                    
 536                                                                                                          
 537     @Override                                                                                            
 538     public void onLauncherProviderChange() {                                                             
 539         if (mLauncherCallbacks != null) {                                                                
 540             mLauncherCallbacks.onLauncherProviderChange();                                               
 541         }                                                                                                
 542     }                                                                                                    
 543                                                                                                          
 544     /** To be overridden by subclasses to hint to Launcher that we have custom content */                
 545     protected boolean hasCustomContentToLeft() {                                                         
 546         if (mLauncherCallbacks != null) {                                                                
 547             return mLauncherCallbacks.hasCustomContentToLeft();                                          
 548         }                                                                                                
 549         return false;                                                                                    
 550     }                                                                                                    
 551                                                                                                          
 552     /**                                                                                                  
 553      * To be overridden by subclasses to populate the custom content container and call                  
 554      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 555      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 556      */                                                                                                  
 557     protected void populateCustomContentContainer() {                                                    
 558         if (mLauncherCallbacks != null) {                                                                
 559             mLauncherCallbacks.populateCustomContentContainer();                                         
 560         }                                                                                                
 561     }                                                                                                    
 562                                                                                                          
 563     /**                                                                                                  
 564      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 565      * ensure the custom content page is added or removed if necessary.                                  
 566      */                                                                                                  
 567     protected void invalidateHasCustomContentToLeft() {                                                  
 568         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 569             // Not bound yet, wait for bindScreens to be called.                                         
 570             return;                                                                                      
 571         }                                                                                                
 572                                                                                                          
 573         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 574             // Create the custom content page and call the subclass to populate it.                      
 575             mWorkspace.createCustomContentContainer();                                                   
 576             populateCustomContentContainer();                                                            
 577         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 578             mWorkspace.removeCustomContentPage();                                                        
 579         }                                                                                                
 580     }                                                                                                    
 581                                                                                                          
 582     @Thunk void checkForLocaleChange() {                                                                 
 583         if (sLocaleConfiguration == null) {                                                              
 584             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 585                 @Override                                                                                
 586                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 587                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 588                     readConfiguration(Launcher.this, localeConfiguration);                               
 589                     return localeConfiguration;                                                          
 590                 }                                                                                        
 591                                                                                                          
 592                 @Override                                                                                
 593                 protected void onPostExecute(LocaleConfiguration result) {                               
 594                     sLocaleConfiguration = result;                                                       
 595                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 596                 }                                                                                        
 597             }.execute();                                                                                 
 598             return;                                                                                      
 599         }                                                                                                
 600                                                                                                          
 601         final Configuration configuration = getResources().getConfiguration();                           
 602                                                                                                          
 603         final String previousLocale = sLocaleConfiguration.locale;                                       
 604         final String locale = configuration.locale.toString();                                           
 605                                                                                                          
 606         final int previousMcc = sLocaleConfiguration.mcc;                                                
 607         final int mcc = configuration.mcc;                                                               
 608                                                                                                          
 609         final int previousMnc = sLocaleConfiguration.mnc;                                                
 610         final int mnc = configuration.mnc;                                                               
 611                                                                                                          
 612         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 613                                                                                                          
 614         if (localeChanged) {                                                                             
 615             sLocaleConfiguration.locale = locale;                                                        
 616             sLocaleConfiguration.mcc = mcc;                                                              
 617             sLocaleConfiguration.mnc = mnc;                                                              
 618                                                                                                          
 619             mIconCache.flush();                                                                          
 620                                                                                                          
 621             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 622             new AsyncTask<Void, Void, Void>() {                                                          
 623                 public Void doInBackground(Void ... args) {                                              
 624                     writeConfiguration(Launcher.this, localeConfiguration);                              
 625                     return null;                                                                         
 626                 }                                                                                        
 627             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 628         }                                                                                                
 629     }                                                                                                    
 630                                                                                                          
 631     @Thunk static class LocaleConfiguration {                                                            
 632         public String locale;                                                                            
 633         public int mcc = -1;                                                                             
 634         public int mnc = -1;                                                                             
 635     }                                                                                                    
 636                                                                                                          
 637     @Thunk static void readConfiguration(Context context, LocaleConfiguration configuration) {           
 638         DataInputStream in = null;                                                                       
 639         try {                                                                                            
 640             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));         
 641             configuration.locale = in.readUTF();                                                         
 642             configuration.mcc = in.readInt();                                                            
 643             configuration.mnc = in.readInt();                                                            
 644         } catch (FileNotFoundException e) {                                                              
 645             // Ignore                                                                                    
 646         } catch (IOException e) {                                                                        
 647             // Ignore                                                                                    
 648         } finally {                                                                                      
 649             if (in != null) {                                                                            
 650                 try {                                                                                    
 651                     in.close();                                                                          
 652                 } catch (IOException e) {                                                                
 653                     // Ignore                                                                            
 654                 }                                                                                        
 655             }                                                                                            
 656         }                                                                                                
 657     }                                                                                                    
 658                                                                                                          
 659     @Thunk static void writeConfiguration(Context context, LocaleConfiguration configuration) {          
 660         DataOutputStream out = null;                                                                     
 661         try {                                                                                            
 662             out = new DataOutputStream(context.openFileOutput(                                           
 663                     LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                  
 664             out.writeUTF(configuration.locale);                                                          
 665             out.writeInt(configuration.mcc);                                                             
 666             out.writeInt(configuration.mnc);                                                             
 667             out.flush();                                                                                 
 668         } catch (FileNotFoundException e) {                                                              
 669             // Ignore                                                                                    
 670         } catch (IOException e) {                                                                        
 671             //noinspection ResultOfMethodCallIgnored                                                     
 672             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                      
 673         } finally {                                                                                      
 674             if (out != null) {                                                                           
 675                 try {                                                                                    
 676                     out.close();                                                                         
 677                 } catch (IOException e) {                                                                
 678                     // Ignore                                                                            
 679                 }                                                                                        
 680             }                                                                                            
 681         }                                                                                                
 682     }                                                                                                    
 683                                                                                                          
 684     public Stats getStats() {                                                                            
 685         return mStats;                                                                                   
 686     }                                                                                                    
 687                                                                                                          
 688     public LayoutInflater getInflater() {                                                                
 689         return mInflater;                                                                                
 690     }                                                                                                    
 691                                                                                                          
 692     public boolean isDraggingEnabled() {                                                                 
 693         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 694         // that is subsequently removed from the workspace in startBinding().                            
 695         return !mModel.isLoadingWorkspace();                                                             
 696     }                                                                                                    
 697                                                                                                          
 698     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                       
 699     public static int generateViewId() {                                                                 
 700         if (Build.VERSION.SDK_INT >= 17) {                                                               
 701             return View.generateViewId();                                                                
 702         } else {                                                                                         
 703             // View.generateViewId() is not available. The following fallback logic is a copy            
 704             // of its implementation.                                                                    
 705             for (;;) {                                                                                   
 706                 final int result = sNextGeneratedId.get();                                               
 707                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 708                 int newValue = result + 1;                                                               
 709                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 710                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 711                     return result;                                                                       
 712                 }                                                                                        
 713             }                                                                                            
 714         }                                                                                                
 715     }                                                                                                    
 716                                                                                                          
 717     public int getViewIdForItem(ItemInfo info) {                                                         
 718         // This cast is safe given the > 2B range for int.                                               
 719         int itemId = (int) info.id;                                                                      
 720         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 721             return mItemIdToViewId.get(itemId);                                                          
 722         }                                                                                                
 723         int viewId = generateViewId();                                                                   
 724         mItemIdToViewId.put(itemId, viewId);                                                             
 725         return viewId;                                                                                   
 726     }                                                                                                    
 727                                                                                                          
 728     /**                                                                                                  
 729      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 730      * a configuration step, this allows the proper animations to run after other transitions.           
 731      */                                                                                                  
 732     private long completeAdd(PendingAddArguments args) {                                                 
 733         long screenId = args.screenId;                                                                   
 734         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 735             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 736             // that the drop page actually exists.                                                       
 737             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 738         }                                                                                                
 739                                                                                                          
 740         switch (args.requestCode) {                                                                      
 741             case REQUEST_CREATE_SHORTCUT:                                                                
 742                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 743                         args.cellY);                                                                     
 744                 break;                                                                                   
 745             case REQUEST_CREATE_APPWIDGET:                                                               
 746                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 747                 break;                                                                                   
 748             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 749                 completeRestoreAppWidget(args.appWidgetId);                                              
 750                 break;                                                                                   
 751         }                                                                                                
 752         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 753         // if you turned the screen off and then back while in All Apps, Launcher would not              
 754         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 755         resetAddInfo();                                                                                  
 756         return screenId;                                                                                 
 757     }                                                                                                    
 758                                                                                                          
 759     private void handleActivityResult(                                                                   
 760             final int requestCode, final int resultCode, final Intent data) {                            
 761         // Reset the startActivity waiting flag                                                          
 762         setWaitingForResult(false);                                                                      
 763         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 764         mPendingAddWidgetId = -1;                                                                        
 765                                                                                                          
 766         Runnable exitSpringLoaded = new Runnable() {                                                     
 767             @Override                                                                                    
 768             public void run() {                                                                          
 769                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 770                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 771             }                                                                                            
 772         };                                                                                               
 773                                                                                                          
 774         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 775             final int appWidgetId = data != null ?                                                       
 776                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 777             if (resultCode == RESULT_CANCELED) {                                                         
 778                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 779                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 780                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 781             } else if (resultCode == RESULT_OK) {                                                        
 782                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 783                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 784             }                                                                                            
 785             return;                                                                                      
 786         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 787             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 788                 mWorkspace.exitOverviewMode(false);                                                      
 789             }                                                                                            
 790             return;                                                                                      
 791         }                                                                                                
 792                                                                                                          
 793         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 794                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 795                                                                                                          
 796         final boolean workspaceLocked = isWorkspaceLocked();                                             
 797         // We have special handling for widgets                                                          
 798         if (isWidgetDrop) {                                                                              
 799             final int appWidgetId;                                                                       
 800             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 801                     : -1;                                                                                
 802             if (widgetId < 0) {                                                                          
 803                 appWidgetId = pendingAddWidgetId;                                                        
 804             } else {                                                                                     
 805                 appWidgetId = widgetId;                                                                  
 806             }                                                                                            
 807                                                                                                          
 808             final int result;                                                                            
 809             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 810                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 811                         "returned from the widget configuration activity.");                             
 812                 result = RESULT_CANCELED;                                                                
 813                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 814                 final Runnable onComplete = new Runnable() {                                             
 815                     @Override                                                                            
 816                     public void run() {                                                                  
 817                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 818                     }                                                                                    
 819                 };                                                                                       
 820                 if (workspaceLocked) {                                                                   
 821                     // No need to remove the empty screen if we're mid-binding, as the                   
 822                     // the bind will not add the empty screen.                                           
 823                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 824                 } else {                                                                                 
 825                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 826                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 827                 }                                                                                        
 828             } else {                                                                                     
 829                 if (!workspaceLocked) {                                                                  
 830                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 831                         // When the screen id represents an actual screen (as opposed to a rank)         
 832                         // we make sure that the drop page actually exists.                              
 833                         mPendingAddInfo.screenId =                                                       
 834                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 835                     }                                                                                    
 836                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 837                                                                                                          
 838                     dropLayout.setDropPending(true);                                                     
 839                     final Runnable onComplete = new Runnable() {                                         
 840                         @Override                                                                        
 841                         public void run() {                                                              
 842                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 843                             dropLayout.setDropPending(false);                                            
 844                         }                                                                                
 845                     };                                                                                   
 846                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 847                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 848                 } else {                                                                                 
 849                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 850                             mPendingAddInfo);                                                            
 851                     sPendingAddItem = args;                                                              
 852                 }                                                                                        
 853             }                                                                                            
 854             return;                                                                                      
 855         }                                                                                                
 856                                                                                                          
 857         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 858             if (resultCode == RESULT_OK) {                                                               
 859                 // Update the widget view.                                                               
 860                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 861                         pendingAddWidgetId, mPendingAddInfo);                                            
 862                 if (workspaceLocked) {                                                                   
 863                     sPendingAddItem = args;                                                              
 864                 } else {                                                                                 
 865                     completeAdd(args);                                                                   
 866                 }                                                                                        
 867             }                                                                                            
 868             // Leave the widget in the pending state if the user canceled the configure.                 
 869             return;                                                                                      
 870         }                                                                                                
 871                                                                                                          
 872         // The pattern used here is that a user PICKs a specific application,                            
 873         // which, depending on the target, might need to CREATE the actual target.                       
 874                                                                                                          
 875         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 876         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 877         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 878             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 879                     mPendingAddInfo);                                                                    
 880             if (isWorkspaceLocked()) {                                                                   
 881                 sPendingAddItem = args;                                                                  
 882             } else {                                                                                     
 883                 completeAdd(args);                                                                       
 884                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 885                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 886             }                                                                                            
 887         } else if (resultCode == RESULT_CANCELED) {                                                      
 888             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 889                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 890         }                                                                                                
 891         mDragLayer.clearAnimatedView();                                                                  
 892                                                                                                          
 893     }                                                                                                    
 894                                                                                                          
 895     @Override                                                                                            
 896     protected void onActivityResult(                                                                     
 897             final int requestCode, final int resultCode, final Intent data) {                            
 898         handleActivityResult(requestCode, resultCode, data);                                             
 899         if (mLauncherCallbacks != null) {                                                                
 900             mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                          
 901         }                                                                                                
 902     }                                                                                                    
 903                                                                                                          
 904     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 905             appWidgetId, ItemInfo info) {                                                                
 906         PendingAddArguments args = new PendingAddArguments();                                            
 907         args.requestCode = requestCode;                                                                  
 908         args.intent = data;                                                                              
 909         args.container = info.container;                                                                 
 910         args.screenId = info.screenId;                                                                   
 911         args.cellX = info.cellX;                                                                         
 912         args.cellY = info.cellY;                                                                         
 913         args.appWidgetId = appWidgetId;                                                                  
 914         return args;                                                                                     
 915     }                                                                                                    
 916                                                                                                          
 917     /**                                                                                                  
 918      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 919      *                                                                                                   
 920      * @param screenId the screen id to check                                                            
 921      * @return the new screen, or screenId if it exists                                                  
 922      */                                                                                                  
 923     private long ensurePendingDropLayoutExists(long screenId) {                                          
 924         CellLayout dropLayout =                                                                          
 925                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 926         if (dropLayout == null) {                                                                        
 927             // it's possible that the add screen was removed because it was                              
 928             // empty and a re-bind occurred                                                              
 929             mWorkspace.addExtraEmptyScreen();                                                            
 930             return mWorkspace.commitExtraEmptyScreen();                                                  
 931         } else {                                                                                         
 932             return screenId;                                                                             
 933         }                                                                                                
 934     }                                                                                                    
 935                                                                                                          
 936     @Thunk void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                
 937         CellLayout cellLayout =                                                                          
 938                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 939         Runnable onCompleteRunnable = null;                                                              
 940         int animationType = 0;                                                                           
 941                                                                                                          
 942         AppWidgetHostView boundWidget = null;                                                            
 943         if (resultCode == RESULT_OK) {                                                                   
 944             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 945             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 946                     mPendingAddWidgetInfo);                                                              
 947             boundWidget = layout;                                                                        
 948             onCompleteRunnable = new Runnable() {                                                        
 949                 @Override                                                                                
 950                 public void run() {                                                                      
 951                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 952                             mPendingAddInfo.screenId, layout, null);                                     
 953                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 954                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 955                 }                                                                                        
 956             };                                                                                           
 957         } else if (resultCode == RESULT_CANCELED) {                                                      
 958             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 959             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 960         }                                                                                                
 961         if (mDragLayer.getAnimatedView() != null) {                                                      
 962             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 963                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 964                     animationType, boundWidget, true);                                                   
 965         } else if (onCompleteRunnable != null) {                                                         
 966             // The animated view may be null in the case of a rotation during widget configuration       
 967             onCompleteRunnable.run();                                                                    
 968         }                                                                                                
 969     }                                                                                                    
 970                                                                                                          
 971     @Override                                                                                            
 972     protected void onStop() {                                                                            
 973         super.onStop();                                                                                  
 974         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
 975                                                                                                          
 976         if (mLauncherCallbacks != null) {                                                                
 977             mLauncherCallbacks.onStop();                                                                 
 978         }                                                                                                
 979     }                                                                                                    
 980                                                                                                          
 981     @Override                                                                                            
 982     protected void onStart() {                                                                           
 983         super.onStart();                                                                                 
 984         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
 985                                                                                                          
 986         if (mLauncherCallbacks != null) {                                                                
 987             mLauncherCallbacks.onStart();                                                                
 988         }                                                                                                
 989     }                                                                                                    
 990                                                                                                          
 991     @Override                                                                                            
 992     protected void onResume() {                                                                          
 993         long startTime = 0;                                                                              
 994         if (DEBUG_RESUME_TIME) {                                                                         
 995             startTime = System.currentTimeMillis();                                                      
 996             Log.v(TAG, "Launcher.onResume()");                                                           
 997         }                                                                                                
 998                                                                                                          
 999         if (mLauncherCallbacks != null) {                                                                
1000             mLauncherCallbacks.preOnResume();                                                            
1001         }                                                                                                
1002                                                                                                          
1003         super.onResume();                                                                                
1004                                                                                                          
1005         // Restore the previous launcher state                                                           
1006         if (mOnResumeState == State.WORKSPACE) {                                                         
1007             showWorkspace(false);                                                                        
1008         } else if (mOnResumeState == State.APPS) {                                                       
1009             showAppsView(false /* animated */, false /* resetListToTop */);                              
1010         } else if (mOnResumeState == State.WIDGETS) {                                                    
1011             showWidgetsView(false, false);                                                               
1012         }                                                                                                
1013         mOnResumeState = State.NONE;                                                                     
1014                                                                                                          
1015         // Background was set to gradient in onPause(), restore to black if in all apps.                 
1016         setWorkspaceBackground(mState == State.WORKSPACE);                                               
1017                                                                                                          
1018         mPaused = false;                                                                                 
1019         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1020             setWorkspaceLoading(true);                                                                   
1021             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
1022             mRestoring = false;                                                                          
1023             mOnResumeNeedsLoad = false;                                                                  
1024         }                                                                                                
1025         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1026             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1027             // execute them here                                                                         
1028             long startTimeCallbacks = 0;                                                                 
1029             if (DEBUG_RESUME_TIME) {                                                                     
1030                 startTimeCallbacks = System.currentTimeMillis();                                         
1031             }                                                                                            
1032                                                                                                          
1033             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1034                 mBindOnResumeCallbacks.get(i).run();                                                     
1035             }                                                                                            
1036             mBindOnResumeCallbacks.clear();                                                              
1037             if (DEBUG_RESUME_TIME) {                                                                     
1038                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1039                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1040             }                                                                                            
1041         }                                                                                                
1042         if (mOnResumeCallbacks.size() > 0) {                                                             
1043             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1044                 mOnResumeCallbacks.get(i).run();                                                         
1045             }                                                                                            
1046             mOnResumeCallbacks.clear();                                                                  
1047         }                                                                                                
1048                                                                                                          
1049         // Reset the pressed state of icons that were locked in the press state while activities         
1050         // were launching                                                                                
1051         if (mWaitingForResume != null) {                                                                 
1052             // Resets the previous workspace icon press state                                            
1053             mWaitingForResume.setStayPressed(false);                                                     
1054         }                                                                                                
1055                                                                                                          
1056         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1057         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1058         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1059         // orientation.                                                                                  
1060         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1061         reinflateQSBIfNecessary();                                                                       
1062                                                                                                          
1063         // Process any items that were added while Launcher was away.                                    
1064         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1065                                                                                                          
1066         if (DEBUG_RESUME_TIME) {                                                                         
1067             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1068         }                                                                                                
1069                                                                                                          
1070         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1071             // If we are resuming and the custom content is the current page, we call onShow().          
1072             // It is also poassible that onShow will instead be called slightly after first layout       
1073             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1074             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1075                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1076             }                                                                                            
1077         }                                                                                                
1078         mWorkspace.updateInteractionForState();                                                          
1079         mWorkspace.onResume();                                                                           
1080                                                                                                          
1081         PackageInstallerCompat.getInstance(this).onResume();                                             
1082                                                                                                          
1083         if (mLauncherCallbacks != null) {                                                                
1084             mLauncherCallbacks.onResume();                                                               
1085         }                                                                                                
1086     }                                                                                                    
1087                                                                                                          
1088     @Override                                                                                            
1089     protected void onPause() {                                                                           
1090         // Ensure that items added to Launcher are queued until Launcher returns                         
1091         InstallShortcutReceiver.enableInstallQueue();                                                    
1092         PackageInstallerCompat.getInstance(this).onPause();                                              
1093                                                                                                          
1094         super.onPause();                                                                                 
1095         mPaused = true;                                                                                  
1096         mDragController.cancelDrag();                                                                    
1097         mDragController.resetLastGestureUpTime();                                                        
1098                                                                                                          
1099         // We call onHide() aggressively. The custom content callbacks should be able to                 
1100         // debounce excess onHide calls.                                                                 
1101         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1102             mWorkspace.getCustomContentCallbacks().onHide();                                             
1103         }                                                                                                
1104                                                                                                          
1105         if (mLauncherCallbacks != null) {                                                                
1106             mLauncherCallbacks.onPause();                                                                
1107         }                                                                                                
1108     }                                                                                                    
1109                                                                                                          
1110     public interface CustomContentCallbacks {                                                            
1111         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1112         // by a onResume or by scrolling otherwise.                                                      
1113         public void onShow(boolean fromResume);                                                          
1114                                                                                                          
1115         // Custom content is completely hidden                                                           
1116         public void onHide();                                                                            
1117                                                                                                          
1118         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1119         public void onScrollProgressChanged(float progress);                                             
1120                                                                                                          
1121         // Indicates whether the user is allowed to scroll away from the custom content.                 
1122         boolean isScrollingAllowed();                                                                    
1123     }                                                                                                    
1124                                                                                                          
1125     public interface LauncherOverlay {                                                                   
1126                                                                                                          
1127         /**                                                                                              
1128          * Touch interaction leading to overscroll has begun                                             
1129          */                                                                                              
1130         public void onScrollInteractionBegin();                                                          
1131                                                                                                          
1132         /**                                                                                              
1133          * Touch interaction related to overscroll has ended                                             
1134          */                                                                                              
1135         public void onScrollInteractionEnd();                                                            
1136                                                                                                          
1137         /**                                                                                              
1138          * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                 
1139          * screen (or in the case of RTL, the rightmost screen).                                         
1140          */                                                                                              
1141         public void onScrollChange(int progress, boolean rtl);                                           
1142                                                                                                          
1143         /**                                                                                              
1144          * Screen has stopped scrolling                                                                  
1145          */                                                                                              
1146         public void onScrollSettled();                                                                   
1147                                                                                                          
1148         /**                                                                                              
1149          * This method can be called by the Launcher in order to force the LauncherOverlay               
1150          * to exit fully immersive mode.                                                                 
1151          */                                                                                              
1152         public void forceExitFullImmersion();                                                            
1153     }                                                                                                    
1154                                                                                                          
1155     public interface LauncherAppsCallbacks {                                                             
1156         /**                                                                                              
1157          * Updates launcher to the available space that AllApps can take so as not to overlap with       
1158          * any other views.                                                                              
1159          */                                                                                              
1160         public void onAllAppsBoundsChanged(Rect bounds);                                                 
1161                                                                                                          
1162         /**                                                                                              
1163          * Called to dismiss all apps if it is showing.                                                  
1164          */                                                                                              
1165         public void dismissAllApps();                                                                    
1166     }                                                                                                    
1167                                                                                                          
1168     public interface LauncherOverlayCallbacks {                                                          
1169         /**                                                                                              
1170          * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,           
1171          * however it doesn't modify any state within the launcher.                                      
1172          */                                                                                              
1173         public boolean canEnterFullImmersion();                                                          
1174                                                                                                          
1175         /**                                                                                              
1176          * Should be called to tell Launcher that the LauncherOverlay will take over interaction,        
1177          * eg. by occupying the full screen and handling all touch events.                               
1178          *                                                                                               
1179          * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this        
1180          *          case, Launcher will modify any necessary state and assumes the overlay is            
1181          *          handling all interaction. If false, the LauncherOverlay should cancel any            
1182          *                                                                                               
1183          */                                                                                              
1184         public boolean enterFullImmersion();                                                             
1185                                                                                                          
1186         /**                                                                                              
1187          * Must be called when exiting fully immersive mode. Indicates to Launcher that it has           
1188          * full control over UI and state.                                                               
1189          */                                                                                              
1190         public void exitFullImmersion();                                                                 
1191     }                                                                                                    
1192                                                                                                          
1193     class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                             
1194                                                                                                          
1195         @Override                                                                                        
1196         public boolean canEnterFullImmersion() {                                                         
1197             return mState == State.WORKSPACE;                                                            
1198         }                                                                                                
1199                                                                                                          
1200         @Override                                                                                        
1201         public boolean enterFullImmersion() {                                                            
1202             if (mState == State.WORKSPACE) {                                                             
1203                 // When fully immersed, disregard any touches which fall through.                        
1204                 mDragLayer.setBlockTouch(true);                                                          
1205                 return true;                                                                             
1206             }                                                                                            
1207             return false;                                                                                
1208         }                                                                                                
1209                                                                                                          
1210         @Override                                                                                        
1211         public void exitFullImmersion() {                                                                
1212             mDragLayer.setBlockTouch(false);                                                             
1213         }                                                                                                
1214     }                                                                                                    
1215                                                                                                          
1216     protected boolean hasSettings() {                                                                    
1217         if (mLauncherCallbacks != null) {                                                                
1218             return mLauncherCallbacks.hasSettings();                                                     
1219         }                                                                                                
1220         return false;                                                                                    
1221     }                                                                                                    
1222                                                                                                          
1223                                                                                                          
1224     public void addToCustomContentPage(View customContent,                                               
1225             CustomContentCallbacks callbacks, String description) {                                      
1226         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1227     }                                                                                                    
1228                                                                                                          
1229     // The custom content needs to offset its content to account for the QSB                             
1230     public int getTopOffsetForCustomContent() {                                                          
1231         return mWorkspace.getPaddingTop();                                                               
1232     }                                                                                                    
1233                                                                                                          
1234     @Override                                                                                            
1235     public Object onRetainNonConfigurationInstance() {                                                   
1236         // Flag the loader to stop early before switching                                                
1237         if (mModel.isCurrentCallbacks(this)) {                                                           
1238             mModel.stopLoader();                                                                         
1239         }                                                                                                
1240         //TODO(hyunyoungs): stop the widgets loader when there is a rotation.                            
1241                                                                                                          
1242         return Boolean.TRUE;                                                                             
1243     }                                                                                                    
1244                                                                                                          
1245     // We can't hide the IME if it was forced open.  So don't bother                                     
1246     @Override                                                                                            
1247     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1248         super.onWindowFocusChanged(hasFocus);                                                            
1249         mHasFocus = hasFocus;                                                                            
1250                                                                                                          
1251         if (mLauncherCallbacks != null) {                                                                
1252             mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                           
1253         }                                                                                                
1254     }                                                                                                    
1255                                                                                                          
1256     private boolean acceptFilter() {                                                                     
1257         final InputMethodManager inputManager = (InputMethodManager)                                     
1258                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1259         return !inputManager.isFullscreenMode();                                                         
1260     }                                                                                                    
1261                                                                                                          
1262     @Override                                                                                            
1263     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1264         final int uniChar = event.getUnicodeChar();                                                      
1265         final boolean handled = super.onKeyDown(keyCode, event);                                         
1266         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1267         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1268             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1269                     keyCode, event);                                                                     
1270             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1271                 // something usable has been typed - start a search                                      
1272                 // the typed text will be retrieved and cleared by                                       
1273                 // showSearchDialog()                                                                    
1274                 // If there are multiple keystrokes before the search dialog takes focus,                
1275                 // onSearchRequested() will be called for every keystroke,                               
1276                 // but it is idempotent, so it's fine.                                                   
1277                 return onSearchRequested();                                                              
1278             }                                                                                            
1279         }                                                                                                
1280                                                                                                          
1281         // Eat the long press event so the keyboard doesn't come up.                                     
1282         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1283             return true;                                                                                 
1284         }                                                                                                
1285                                                                                                          
1286         return handled;                                                                                  
1287     }                                                                                                    
1288                                                                                                          
1289     private String getTypedText() {                                                                      
1290         return mDefaultKeySsb.toString();                                                                
1291     }                                                                                                    
1292                                                                                                          
1293     private void clearTypedText() {                                                                      
1294         mDefaultKeySsb.clear();                                                                          
1295         mDefaultKeySsb.clearSpans();                                                                     
1296         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1297     }                                                                                                    
1298                                                                                                          
1299     /**                                                                                                  
1300      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1301      * State                                                                                             
1302      */                                                                                                  
1303     private static State intToState(int stateOrdinal) {                                                  
1304         State state = State.WORKSPACE;                                                                   
1305         final State[] stateValues = State.values();                                                      
1306         for (int i = 0; i < stateValues.length; i++) {                                                   
1307             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1308                 state = stateValues[i];                                                                  
1309                 break;                                                                                   
1310             }                                                                                            
1311         }                                                                                                
1312         return state;                                                                                    
1313     }                                                                                                    
1314                                                                                                          
1315     /**                                                                                                  
1316      * Restores the previous state, if it exists.                                                        
1317      *                                                                                                   
1318      * @param savedState The previous state.                                                             
1319      */                                                                                                  
1320     @SuppressWarnings("unchecked")                                                                       
1321     private void restoreState(Bundle savedState) {                                                       
1322         if (savedState == null) {                                                                        
1323             return;                                                                                      
1324         }                                                                                                
1325                                                                                                          
1326         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1327         if (state == State.APPS || state == State.WIDGETS) {                                             
1328             mOnResumeState = state;                                                                      
1329         }                                                                                                
1330                                                                                                          
1331         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1332                 PagedView.INVALID_RESTORE_PAGE);                                                         
1333         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1334             mWorkspace.setRestorePage(currentScreen);                                                    
1335         }                                                                                                
1336                                                                                                          
1337         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1338         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1339                                                                                                          
1340         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1341             mPendingAddInfo.container = pendingAddContainer;                                             
1342             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1343             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1344             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1345             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1346             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1347             AppWidgetProviderInfo info = savedState.getParcelable(                                       
1348                     RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);                                              
1349             mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this, info);          
1350             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1351             setWaitingForResult(true);                                                                   
1352             mRestoring = true;                                                                           
1353         }                                                                                                
1354                                                                                                          
1355         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1356         if (renameFolder) {                                                                              
1357             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1358             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1359             mRestoring = true;                                                                           
1360         }                                                                                                
1361                                                                                                          
1362         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1363                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1364     }                                                                                                    
1365                                                                                                          
1366     /**                                                                                                  
1367      * Finds all the views we need and configure them properly.                                          
1368      */                                                                                                  
1369     private void setupViews() {                                                                          
1370         final DragController dragController = mDragController;                                           
1371                                                                                                          
1372         mLauncherView = findViewById(R.id.launcher);                                                     
1373         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1374         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1375         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1376         mWorkspace.setPageSwitchListener(this);                                                          
1377         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1378                                                                                                          
1379         mLauncherView.setSystemUiVisibility(                                                             
1380                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1381         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1382                                                                                                          
1383         // Setup the drag layer                                                                          
1384         mDragLayer.setup(this, dragController);                                                          
1385                                                                                                          
1386         // Setup the hotseat                                                                             
1387         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1388         if (mHotseat != null) {                                                                          
1389             mHotseat.setup(this);                                                                        
1390             mHotseat.setOnLongClickListener(this);                                                       
1391         }                                                                                                
1392                                                                                                          
1393         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1394         View widgetButton = findViewById(R.id.widget_button);                                            
1395         widgetButton.setOnClickListener(new OnClickListener() {                                          
1396             @Override                                                                                    
1397             public void onClick(View arg0) {                                                             
1398                 if (!mWorkspace.isSwitchingState()) {                                                    
1399                     onClickAddWidgetButton(arg0);                                                        
1400                 }                                                                                        
1401             }                                                                                            
1402         });                                                                                              
1403         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1404                                                                                                          
1405         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1406         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1407             @Override                                                                                    
1408             public void onClick(View arg0) {                                                             
1409                 if (!mWorkspace.isSwitchingState()) {                                                    
1410                     onClickWallpaperPicker(arg0);                                                        
1411                 }                                                                                        
1412             }                                                                                            
1413         });                                                                                              
1414         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1415                                                                                                          
1416         View settingsButton = findViewById(R.id.settings_button);                                        
1417         if (hasSettings()) {                                                                             
1418             settingsButton.setOnClickListener(new OnClickListener() {                                    
1419                 @Override                                                                                
1420                 public void onClick(View arg0) {                                                         
1421                     if (!mWorkspace.isSwitchingState()) {                                                
1422                         onClickSettingsButton(arg0);                                                     
1423                     }                                                                                    
1424                 }                                                                                        
1425             });                                                                                          
1426             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1427         } else {                                                                                         
1428             settingsButton.setVisibility(View.GONE);                                                     
1429         }                                                                                                
1430                                                                                                          
1431         mOverviewPanel.setAlpha(0f);                                                                     
1432                                                                                                          
1433         // Setup the workspace                                                                           
1434         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1435         mWorkspace.setOnLongClickListener(this);                                                         
1436         mWorkspace.setup(dragController);                                                                
1437         dragController.addDragListener(mWorkspace);                                                      
1438                                                                                                          
1439         // Get the search/delete bar                                                                     
1440         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1441                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1442                                                                                                          
1443         // Setup Apps                                                                                    
1444         mAppsView = (AppsContainerView) findViewById(R.id.apps_view);                                    
1445         if (mLauncherCallbacks != null && mLauncherCallbacks.overrideAllAppsSearch()) {                  
1446             mAppsView.hideSearchBar();                                                                   
1447         }                                                                                                
1448                                                                                                          
1449         // Setup AppsCustomize                                                                           
1450         mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);                           
1451                                                                                                          
1452         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1453         dragController.setDragScoller(mWorkspace);                                                       
1454         dragController.setScrollView(mDragLayer);                                                        
1455         dragController.setMoveTarget(mWorkspace);                                                        
1456         dragController.addDropTarget(mWorkspace);                                                        
1457         if (mSearchDropTargetBar != null) {                                                              
1458             mSearchDropTargetBar.setup(this, dragController);                                            
1459             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
1460         }                                                                                                
1461                                                                                                          
1462         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1463             Log.v(TAG, "adding WeightWatcher");                                                          
1464             mWeightWatcher = new WeightWatcher(this);                                                    
1465             mWeightWatcher.setAlpha(0.5f);                                                               
1466             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1467                     new FrameLayout.LayoutParams(                                                        
1468                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1469                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1470                             Gravity.BOTTOM)                                                              
1471             );                                                                                           
1472                                                                                                          
1473             boolean show = shouldShowWeightWatcher();                                                    
1474             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1475         }                                                                                                
1476     }                                                                                                    
1477                                                                                                          
1478     /**                                                                                                  
1479      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1480      */                                                                                                  
1481     public void setAllAppsButton(View allAppsButton) {                                                   
1482         mAllAppsButton = allAppsButton;                                                                  
1483     }                                                                                                    
1484                                                                                                          
1485     public View getAllAppsButton() {                                                                     
1486         return mAllAppsButton;                                                                           
1487     }                                                                                                    
1488                                                                                                          
1489     /**                                                                                                  
1490      * Creates a view representing a shortcut.                                                           
1491      *                                                                                                   
1492      * @param info The data structure describing the shortcut.                                           
1493      *                                                                                                   
1494      * @return A View inflated from R.layout.application.                                                
1495      */                                                                                                  
1496     View createShortcut(ShortcutInfo info) {                                                             
1497         return createShortcut(R.layout.application,                                                      
1498                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1499     }                                                                                                    
1500                                                                                                          
1501     /**                                                                                                  
1502      * Creates a view representing a shortcut inflated from the specified resource.                      
1503      *                                                                                                   
1504      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1505      * @param parent The group the shortcut belongs to.                                                  
1506      * @param info The data structure describing the shortcut.                                           
1507      *                                                                                                   
1508      * @return A View inflated from layoutResId.                                                         
1509      */                                                                                                  
1510     public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                   
1511         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1512         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1513         favorite.setOnClickListener(this);                                                               
1514         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1515         return favorite;                                                                                 
1516     }                                                                                                    
1517                                                                                                          
1518     /**                                                                                                  
1519      * Add a shortcut to the workspace.                                                                  
1520      *                                                                                                   
1521      * @param data The intent describing the shortcut.                                                   
1522      * @param cellInfo The position on screen where to create the shortcut.                              
1523      */                                                                                                  
1524     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1525             int cellY) {                                                                                 
1526         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1527         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1528         CellLayout layout = getCellLayout(container, screenId);                                          
1529                                                                                                          
1530         boolean foundCellSpan = false;                                                                   
1531                                                                                                          
1532         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                   
1533         if (info == null) {                                                                              
1534             return;                                                                                      
1535         }                                                                                                
1536         final View view = createShortcut(info);                                                          
1537                                                                                                          
1538         // First we check if we already know the exact location where we want to add this item.          
1539         if (cellX >= 0 && cellY >= 0) {                                                                  
1540             cellXY[0] = cellX;                                                                           
1541             cellXY[1] = cellY;                                                                           
1542             foundCellSpan = true;                                                                        
1543                                                                                                          
1544             // If appropriate, either create a folder or add to an existing folder                       
1545             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1546                     true, null,null)) {                                                                  
1547                 return;                                                                                  
1548             }                                                                                            
1549             DragObject dragObject = new DragObject();                                                    
1550             dragObject.dragInfo = info;                                                                  
1551             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1552                     true)) {                                                                             
1553                 return;                                                                                  
1554             }                                                                                            
1555         } else if (touchXY != null) {                                                                    
1556             // when dragging and dropping, just find the closest free spot                               
1557             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1558             foundCellSpan = (result != null);                                                            
1559         } else {                                                                                         
1560             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1561         }                                                                                                
1562                                                                                                          
1563         if (!foundCellSpan) {                                                                            
1564             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1565             return;                                                                                      
1566         }                                                                                                
1567                                                                                                          
1568         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1]);          
1569                                                                                                          
1570         if (!mRestoring) {                                                                               
1571             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1572                     isWorkspaceLocked());                                                                
1573         }                                                                                                
1574     }                                                                                                    
1575                                                                                                          
1576     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1577             int minHeight) {                                                                             
1578         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1579         // We want to account for the extra amount of padding that we are adding to the widget           
1580         // to ensure that it gets the full amount of space that it has requested                         
1581         int requiredWidth = minWidth + padding.left + padding.right;                                     
1582         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1583         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1584     }                                                                                                    
1585                                                                                                          
1586     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1587         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1588     }                                                                                                    
1589                                                                                                          
1590     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1591         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1592     }                                                                                                    
1593                                                                                                          
1594     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1595         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1596     }                                                                                                    
1597                                                                                                          
1598     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1599         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1600                 info.minResizeHeight);                                                                   
1601     }                                                                                                    
1602                                                                                                          
1603     /**                                                                                                  
1604      * Add a widget to the workspace.                                                                    
1605      *                                                                                                   
1606      * @param appWidgetId The app widget id                                                              
1607      */                                                                                                  
1608     @Thunk void completeAddAppWidget(int appWidgetId, long container, long screenId,                     
1609             AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                   
1610                                                                                                          
1611         ItemInfo info = mPendingAddInfo;                                                                 
1612         if (appWidgetInfo == null) {                                                                     
1613             appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                         
1614                     mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                    
1615         }                                                                                                
1616                                                                                                          
1617         if (appWidgetInfo.isCustomWidget) {                                                              
1618             appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                        
1619         }                                                                                                
1620                                                                                                          
1621         LauncherAppWidgetInfo launcherInfo;                                                              
1622         launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                   
1623         launcherInfo.spanX = info.spanX;                                                                 
1624         launcherInfo.spanY = info.spanY;                                                                 
1625         launcherInfo.minSpanX = info.minSpanX;                                                           
1626         launcherInfo.minSpanY = info.minSpanY;                                                           
1627         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1628                                                                                                          
1629         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1630                 container, screenId, info.cellX, info.cellY);                                            
1631                                                                                                          
1632         if (!mRestoring) {                                                                               
1633             if (hostView == null) {                                                                      
1634                 // Perform actual inflation because we're live                                           
1635                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                     
1636                         appWidgetInfo);                                                                  
1637             } else {                                                                                     
1638                 // The AppWidgetHostView has already been inflated and instantiated                      
1639                 launcherInfo.hostView = hostView;                                                        
1640             }                                                                                            
1641             launcherInfo.hostView.setTag(launcherInfo);                                                  
1642             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1643             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1644                                                                                                          
1645             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,               
1646                     info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());            
1647                                                                                                          
1648             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1649         }                                                                                                
1650         resetAddInfo();                                                                                  
1651     }                                                                                                    
1652                                                                                                          
1653     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1654         @Override                                                                                        
1655         public void onReceive(Context context, Intent intent) {                                          
1656             final String action = intent.getAction();                                                    
1657             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1658                 mUserPresent = false;                                                                    
1659                 mDragLayer.clearAllResizeFrames();                                                       
1660                 updateAutoAdvanceState();                                                                
1661                                                                                                          
1662                 // Reset AllApps to its initial state only if we are not in the middle of                
1663                 // processing a multi-step drop                                                          
1664                 if (mAppsView != null && mWidgetsView != null &&                                         
1665                         mPendingAddInfo.container == ItemInfo.NO_ID) {                                   
1666                     showWorkspace(false);                                                                
1667                 }                                                                                        
1668             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1669                 mUserPresent = true;                                                                     
1670                 updateAutoAdvanceState();                                                                
1671             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1672                 mModel.resetLoadedState(false, true);                                                    
1673                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1674                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1675             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1676                 mModel.resetLoadedState(false, true);                                                    
1677                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1678                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1679                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1680             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                    
1681                     || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {               
1682                 getModel().forceReload();                                                                
1683             }                                                                                            
1684         }                                                                                                
1685     };                                                                                                   
1686                                                                                                          
1687     @Override                                                                                            
1688     public void onAttachedToWindow() {                                                                   
1689         super.onAttachedToWindow();                                                                      
1690                                                                                                          
1691         // Listen for broadcasts related to user-presence                                                
1692         final IntentFilter filter = new IntentFilter();                                                  
1693         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1694         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1695         // For handling managed profiles                                                                 
1696         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1697         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1698         if (ENABLE_DEBUG_INTENTS) {                                                                      
1699             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1700             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1701         }                                                                                                
1702         registerReceiver(mReceiver, filter);                                                             
1703         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1704         setupTransparentSystemBarsForLmp();                                                              
1705         mAttached = true;                                                                                
1706         mVisible = true;                                                                                 
1707     }                                                                                                    
1708                                                                                                          
1709     /**                                                                                                  
1710      * Sets up transparent navigation and status bars in LMP.                                            
1711      * This method is a no-op for other platform versions.                                               
1712      */                                                                                                  
1713     @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                             
1714     private void setupTransparentSystemBarsForLmp() {                                                    
1715         if (Utilities.isLmpOrAbove()) {                                                                  
1716             Window window = getWindow();                                                                 
1717             window.getAttributes().systemUiVisibility |=                                                 
1718                     (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                   
1719                             | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                      
1720                             | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                               
1721             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1722                     | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                           
1723             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);               
1724             window.setStatusBarColor(Color.TRANSPARENT);                                                 
1725             window.setNavigationBarColor(Color.TRANSPARENT);                                             
1726         }                                                                                                
1727     }                                                                                                    
1728                                                                                                          
1729     @Override                                                                                            
1730     public void onDetachedFromWindow() {                                                                 
1731         super.onDetachedFromWindow();                                                                    
1732         mVisible = false;                                                                                
1733                                                                                                          
1734         if (mAttached) {                                                                                 
1735             unregisterReceiver(mReceiver);                                                               
1736             mAttached = false;                                                                           
1737         }                                                                                                
1738         updateAutoAdvanceState();                                                                        
1739     }                                                                                                    
1740                                                                                                          
1741     public void onWindowVisibilityChanged(int visibility) {                                              
1742         mVisible = visibility == View.VISIBLE;                                                           
1743         updateAutoAdvanceState();                                                                        
1744         // The following code used to be in onResume, but it turns out onResume is called when           
1745         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1746         // is a more appropriate event to handle                                                         
1747         if (mVisible) {                                                                                  
1748             if (!mWorkspaceLoading) {                                                                    
1749                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1750                 // We want to let Launcher draw itself at least once before we force it to build         
1751                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1752                 // apps is nice and speedy.                                                              
1753                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1754                     private boolean mStarted = false;                                                    
1755                     public void onDraw() {                                                               
1756                         if (mStarted) return;                                                            
1757                         mStarted = true;                                                                 
1758                         // We delay the layer building a bit in order to give                            
1759                         // other message processing a time to run.  In particular                        
1760                         // this avoids a delay in hiding the IME if it was                               
1761                         // currently shown, because doing that may involve                               
1762                         // some communication back with the app.                                         
1763                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1764                         final ViewTreeObserver.OnDrawListener listener = this;                           
1765                         mWorkspace.post(new Runnable() {                                                 
1766                                 public void run() {                                                      
1767                                     if (mWorkspace != null &&                                            
1768                                             mWorkspace.getViewTreeObserver() != null) {                  
1769                                         mWorkspace.getViewTreeObserver().                                
1770                                                 removeOnDrawListener(listener);                          
1771                                     }                                                                    
1772                                 }                                                                        
1773                             });                                                                          
1774                         return;                                                                          
1775                     }                                                                                    
1776                 });                                                                                      
1777             }                                                                                            
1778             clearTypedText();                                                                            
1779         }                                                                                                
1780     }                                                                                                    
1781                                                                                                          
1782     @Thunk void sendAdvanceMessage(long delay) {                                                         
1783         mHandler.removeMessages(ADVANCE_MSG);                                                            
1784         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1785         mHandler.sendMessageDelayed(msg, delay);                                                         
1786         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1787     }                                                                                                    
1788                                                                                                          
1789     @Thunk void updateAutoAdvanceState() {                                                               
1790         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1791         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1792             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1793             if (autoAdvanceRunning) {                                                                    
1794                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1795                 sendAdvanceMessage(delay);                                                               
1796             } else {                                                                                     
1797                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1798                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1799                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1800                 }                                                                                        
1801                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1802                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1803             }                                                                                            
1804         }                                                                                                
1805     }                                                                                                    
1806                                                                                                          
1807     private final Handler mHandler = new Handler() {                                                     
1808         @Override                                                                                        
1809         public void handleMessage(Message msg) {                                                         
1810             if (msg.what == ADVANCE_MSG) {                                                               
1811                 int i = 0;                                                                               
1812                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1813                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1814                     final int delay = mAdvanceStagger * i;                                               
1815                     if (v instanceof Advanceable) {                                                      
1816                        postDelayed(new Runnable() {                                                      
1817                            public void run() {                                                           
1818                                ((Advanceable) v).advance();                                              
1819                            }                                                                             
1820                        }, delay);                                                                        
1821                     }                                                                                    
1822                     i++;                                                                                 
1823                 }                                                                                        
1824                 sendAdvanceMessage(mAdvanceInterval);                                                    
1825             }                                                                                            
1826         }                                                                                                
1827     };                                                                                                   
1828                                                                                                          
1829     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1830         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1831         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1832         if (v instanceof Advanceable) {                                                                  
1833             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1834             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1835             updateAutoAdvanceState();                                                                    
1836         }                                                                                                
1837     }                                                                                                    
1838                                                                                                          
1839     void removeWidgetToAutoAdvance(View hostView) {                                                      
1840         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1841             mWidgetsToAdvance.remove(hostView);                                                          
1842             updateAutoAdvanceState();                                                                    
1843         }                                                                                                
1844     }                                                                                                    
1845                                                                                                          
1846     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1847         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1848         launcherInfo.hostView = null;                                                                    
1849     }                                                                                                    
1850                                                                                                          
1851     public void showOutOfSpaceMessage(boolean isHotseatLayout) {                                         
1852         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1853         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1854     }                                                                                                    
1855                                                                                                          
1856     public DragLayer getDragLayer() {                                                                    
1857         return mDragLayer;                                                                               
1858     }                                                                                                    
1859                                                                                                          
1860     public AppsContainerView getAppsView() {                                                             
1861         return mAppsView;                                                                                
1862     }                                                                                                    
1863                                                                                                          
1864     public WidgetsContainerView getWidgetsView() {                                                       
1865         return mWidgetsView;                                                                             
1866     }                                                                                                    
1867                                                                                                          
1868     public Workspace getWorkspace() {                                                                    
1869         return mWorkspace;                                                                               
1870     }                                                                                                    
1871                                                                                                          
1872     public Hotseat getHotseat() {                                                                        
1873         return mHotseat;                                                                                 
1874     }                                                                                                    
1875                                                                                                          
1876     public ViewGroup getOverviewPanel() {                                                                
1877         return mOverviewPanel;                                                                           
1878     }                                                                                                    
1879                                                                                                          
1880     public SearchDropTargetBar getSearchBar() {                                                          
1881         return mSearchDropTargetBar;                                                                     
1882     }                                                                                                    
1883                                                                                                          
1884     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1885         return mAppWidgetHost;                                                                           
1886     }                                                                                                    
1887                                                                                                          
1888     public LauncherModel getModel() {                                                                    
1889         return mModel;                                                                                   
1890     }                                                                                                    
1891                                                                                                          
1892     protected SharedPreferences getSharedPrefs() {                                                       
1893         return mSharedPrefs;                                                                             
1894     }                                                                                                    
1895                                                                                                          
1896     public void closeSystemDialogs() {                                                                   
1897         getWindow().closeAllPanels();                                                                    
1898                                                                                                          
1899         // Whatever we were doing is hereby canceled.                                                    
1900         setWaitingForResult(false);                                                                      
1901     }                                                                                                    
1902                                                                                                          
1903     @Override                                                                                            
1904     protected void onNewIntent(Intent intent) {                                                          
1905         long startTime = 0;                                                                              
1906         if (DEBUG_RESUME_TIME) {                                                                         
1907             startTime = System.currentTimeMillis();                                                      
1908         }                                                                                                
1909         super.onNewIntent(intent);                                                                       
1910                                                                                                          
1911         // Close the menu                                                                                
1912         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1913             // also will cancel mWaitingForResult.                                                       
1914             closeSystemDialogs();                                                                        
1915                                                                                                          
1916             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1917                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1918                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1919                                                                                                          
1920             if (mWorkspace == null) {                                                                    
1921                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1922                 return;                                                                                  
1923             }                                                                                            
1924             Folder openFolder = mWorkspace.getOpenFolder();                                              
1925             // In all these cases, only animate if we're already on home                                 
1926             mWorkspace.exitWidgetResizeMode();                                                           
1927                                                                                                          
1928             boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                   
1929                     mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                   
1930             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1931                     openFolder == null && moveToDefaultScreen) {                                         
1932                 mWorkspace.moveToDefaultScreen(true);                                                    
1933             }                                                                                            
1934                                                                                                          
1935             closeFolder();                                                                               
1936             exitSpringLoadedDragMode();                                                                  
1937                                                                                                          
1938             // If we are already on home, then just animate back to the workspace,                       
1939             // otherwise, just wait until onResume to set the state back to Workspace                    
1940             if (alreadyOnHome) {                                                                         
1941                 showWorkspace(true);                                                                     
1942             } else {                                                                                     
1943                 mOnResumeState = State.WORKSPACE;                                                        
1944             }                                                                                            
1945                                                                                                          
1946             final View v = getWindow().peekDecorView();                                                  
1947             if (v != null && v.getWindowToken() != null) {                                               
1948                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1949                         INPUT_METHOD_SERVICE);                                                           
1950                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1951             }                                                                                            
1952                                                                                                          
1953             // Reset the apps view                                                                       
1954             if (!alreadyOnHome && mAppsView != null) {                                                   
1955                 mAppsView.scrollToTop();                                                                 
1956             }                                                                                            
1957                                                                                                          
1958             // Reset the widgets view                                                                    
1959             if (!alreadyOnHome && mWidgetsView != null) {                                                
1960                 mWidgetsView.scrollToTop();                                                              
1961             }                                                                                            
1962                                                                                                          
1963             if (mLauncherCallbacks != null) {                                                            
1964                 mLauncherCallbacks.onHomeIntent();                                                       
1965             }                                                                                            
1966         }                                                                                                
1967                                                                                                          
1968         if (DEBUG_RESUME_TIME) {                                                                         
1969             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1970         }                                                                                                
1971                                                                                                          
1972         if (mLauncherCallbacks != null) {                                                                
1973             mLauncherCallbacks.onNewIntent(intent);                                                      
1974         }                                                                                                
1975     }                                                                                                    
1976                                                                                                          
1977     @Override                                                                                            
1978     public void onRestoreInstanceState(Bundle state) {                                                   
1979         super.onRestoreInstanceState(state);                                                             
1980         for (int page: mSynchronouslyBoundPages) {                                                       
1981             mWorkspace.restoreInstanceStateForChild(page);                                               
1982         }                                                                                                
1983     }                                                                                                    
1984                                                                                                          
1985     @Override                                                                                            
1986     protected void onSaveInstanceState(Bundle outState) {                                                
1987         if (mWorkspace.getChildCount() > 0) {                                                            
1988             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1989                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1990         }                                                                                                
1991         super.onSaveInstanceState(outState);                                                             
1992                                                                                                          
1993         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1994         // We close any open folder since it will not be re-opened, and we need to make sure             
1995         // this state is reflected.                                                                      
1996         closeFolder();                                                                                   
1997                                                                                                          
1998         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
1999                 mWaitingForResult) {                                                                     
2000             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
2001             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
2002             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
2003             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
2004             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
2005             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
2006             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
2007             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
2008         }                                                                                                
2009                                                                                                          
2010         if (mFolderInfo != null && mWaitingForResult) {                                                  
2011             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
2012             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
2013         }                                                                                                
2014                                                                                                          
2015         // Save the current widgets tray?                                                                
2016         // TODO(hyunyoungs)                                                                              
2017         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
2018                                                                                                          
2019         if (mLauncherCallbacks != null) {                                                                
2020             mLauncherCallbacks.onSaveInstanceState(outState);                                            
2021         }                                                                                                
2022     }                                                                                                    
2023                                                                                                          
2024     @Override                                                                                            
2025     public void onDestroy() {                                                                            
2026         super.onDestroy();                                                                               
2027                                                                                                          
2028         // Remove all pending runnables                                                                  
2029         mHandler.removeMessages(ADVANCE_MSG);                                                            
2030         mHandler.removeMessages(0);                                                                      
2031         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2032                                                                                                          
2033         // Stop callbacks from LauncherModel                                                             
2034         LauncherAppState app = (LauncherAppState.getInstance());                                         
2035                                                                                                          
2036         // It's possible to receive onDestroy after a new Launcher activity has                          
2037         // been created. In this case, don't interfere with the new Launcher.                            
2038         if (mModel.isCurrentCallbacks(this)) {                                                           
2039             mModel.stopLoader();                                                                         
2040             app.setLauncher(null);                                                                       
2041         }                                                                                                
2042                                                                                                          
2043         try {                                                                                            
2044             mAppWidgetHost.stopListening();                                                              
2045         } catch (NullPointerException ex) {                                                              
2046             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2047         }                                                                                                
2048         mAppWidgetHost = null;                                                                           
2049                                                                                                          
2050         mWidgetsToAdvance.clear();                                                                       
2051                                                                                                          
2052         TextKeyListener.getInstance().release();                                                         
2053                                                                                                          
2054         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2055         // to prevent leaking Launcher activities on orientation change.                                 
2056         if (mModel != null) {                                                                            
2057             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2058         }                                                                                                
2059                                                                                                          
2060         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2061         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2062                                                                                                          
2063         mDragLayer.clearAllResizeFrames();                                                               
2064         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2065         mWorkspace.removeAllWorkspaceScreens();                                                          
2066         mWorkspace = null;                                                                               
2067         mDragController = null;                                                                          
2068                                                                                                          
2069         LauncherAnimUtils.onDestroyActivity();                                                           
2070                                                                                                          
2071         if (mLauncherCallbacks != null) {                                                                
2072             mLauncherCallbacks.onDestroy();                                                              
2073         }                                                                                                
2074     }                                                                                                    
2075                                                                                                          
2076     public DragController getDragController() {                                                          
2077         return mDragController;                                                                          
2078     }                                                                                                    
2079                                                                                                          
2080     @Override                                                                                            
2081     public void startActivityForResult(Intent intent, int requestCode) {                                 
2082         onStartForResult(requestCode);                                                                   
2083         super.startActivityForResult(intent, requestCode);                                               
2084     }                                                                                                    
2085                                                                                                          
2086     @Override                                                                                            
2087     public void startIntentSenderForResult (IntentSender intent, int requestCode,                        
2088             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {       
2089         onStartForResult(requestCode);                                                                   
2090         try {                                                                                            
2091             super.startIntentSenderForResult(intent, requestCode,                                        
2092                 fillInIntent, flagsMask, flagsValues, extraFlags, options);                              
2093         } catch (IntentSender.SendIntentException e) {                                                   
2094             throw new ActivityNotFoundException();                                                       
2095         }                                                                                                
2096     }                                                                                                    
2097                                                                                                          
2098     private void onStartForResult(int requestCode) {                                                     
2099         if (requestCode >= 0) {                                                                          
2100             setWaitingForResult(true);                                                                   
2101         }                                                                                                
2102     }                                                                                                    
2103                                                                                                          
2104     /**                                                                                                  
2105      * Indicates that we want global search for this activity by setting the globalSearch                
2106      * argument for {@link #startSearch} to true.                                                        
2107      */                                                                                                  
2108     @Override                                                                                            
2109     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2110             Bundle appSearchData, boolean globalSearch) {                                                
2111                                                                                                          
2112         showWorkspace(true);                                                                             
2113                                                                                                          
2114         if (initialQuery == null) {                                                                      
2115             // Use any text typed in the launcher as the initial query                                   
2116             initialQuery = getTypedText();                                                               
2117         }                                                                                                
2118         if (appSearchData == null) {                                                                     
2119             appSearchData = new Bundle();                                                                
2120             appSearchData.putString("source", "launcher-search");                                        
2121         }                                                                                                
2122         Rect sourceBounds = new Rect();                                                                  
2123         if (mSearchDropTargetBar != null) {                                                              
2124             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2125         }                                                                                                
2126                                                                                                          
2127         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2128                 appSearchData, sourceBounds);                                                            
2129         if (clearTextImmediately) {                                                                      
2130             clearTypedText();                                                                            
2131         }                                                                                                
2132     }                                                                                                    
2133                                                                                                          
2134     /**                                                                                                  
2135      * Start a text search.                                                                              
2136      *                                                                                                   
2137      * @return {@code true} if the search will start immediately, so any further keypresses              
2138      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2139      * to buffer keypresses.                                                                             
2140      */                                                                                                  
2141     public boolean startSearch(String initialQuery,                                                      
2142             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2143         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
2144             return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,       
2145                     sourceBounds);                                                                       
2146         }                                                                                                
2147                                                                                                          
2148         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2149                 appSearchData, sourceBounds);                                                            
2150         return false;                                                                                    
2151     }                                                                                                    
2152                                                                                                          
2153     /**                                                                                                  
2154      * Starts the global search activity. This code is a copied from SearchManager                       
2155      */                                                                                                  
2156     private void startGlobalSearch(String initialQuery,                                                  
2157             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2158         final SearchManager searchManager =                                                              
2159             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2160         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2161         if (globalSearchActivity == null) {                                                              
2162             Log.w(TAG, "No global search activity found.");                                              
2163             return;                                                                                      
2164         }                                                                                                
2165         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2166         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2167         intent.setComponent(globalSearchActivity);                                                       
2168         // Make sure that we have a Bundle to put source in                                              
2169         if (appSearchData == null) {                                                                     
2170             appSearchData = new Bundle();                                                                
2171         } else {                                                                                         
2172             appSearchData = new Bundle(appSearchData);                                                   
2173         }                                                                                                
2174         // Set source to package name of app that starts global search if not set already.               
2175         if (!appSearchData.containsKey("source")) {                                                      
2176             appSearchData.putString("source", getPackageName());                                         
2177         }                                                                                                
2178         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2179         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2180             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2181         }                                                                                                
2182         if (selectInitialQuery) {                                                                        
2183             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2184         }                                                                                                
2185         intent.setSourceBounds(sourceBounds);                                                            
2186         try {                                                                                            
2187             startActivity(intent);                                                                       
2188         } catch (ActivityNotFoundException ex) {                                                         
2189             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2190         }                                                                                                
2191     }                                                                                                    
2192                                                                                                          
2193     public boolean isOnCustomContent() {                                                                 
2194         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2195     }                                                                                                    
2196                                                                                                          
2197     @Override                                                                                            
2198     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2199         super.onPrepareOptionsMenu(menu);                                                                
2200         if (!isOnCustomContent()) {                                                                      
2201             // Close any open folders                                                                    
2202             closeFolder();                                                                               
2203             // Stop resizing any widgets                                                                 
2204             mWorkspace.exitWidgetResizeMode();                                                           
2205             if (!mWorkspace.isInOverviewMode()) {                                                        
2206                 // Show the overview mode                                                                
2207                 showOverviewMode(true);                                                                  
2208             } else {                                                                                     
2209                 showWorkspace(true);                                                                     
2210             }                                                                                            
2211         }                                                                                                
2212         if (mLauncherCallbacks != null) {                                                                
2213             return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                        
2214         }                                                                                                
2215                                                                                                          
2216         return false;                                                                                    
2217     }                                                                                                    
2218                                                                                                          
2219     @Override                                                                                            
2220     public boolean onSearchRequested() {                                                                 
2221         startSearch(null, false, null, true);                                                            
2222         // Use a custom animation for launching search                                                   
2223         return true;                                                                                     
2224     }                                                                                                    
2225                                                                                                          
2226     public boolean isWorkspaceLocked() {                                                                 
2227         return mWorkspaceLoading || mWaitingForResult;                                                   
2228     }                                                                                                    
2229                                                                                                          
2230     public boolean isWorkspaceLoading() {                                                                
2231         return mWorkspaceLoading;                                                                        
2232     }                                                                                                    
2233                                                                                                          
2234     private void setWorkspaceLoading(boolean value) {                                                    
2235         boolean isLocked = isWorkspaceLocked();                                                          
2236         mWorkspaceLoading = value;                                                                       
2237         if (isLocked != isWorkspaceLocked()) {                                                           
2238             onWorkspaceLockedChanged();                                                                  
2239         }                                                                                                
2240     }                                                                                                    
2241                                                                                                          
2242     private void setWaitingForResult(boolean value) {                                                    
2243         boolean isLocked = isWorkspaceLocked();                                                          
2244         mWaitingForResult = value;                                                                       
2245         if (isLocked != isWorkspaceLocked()) {                                                           
2246             onWorkspaceLockedChanged();                                                                  
2247         }                                                                                                
2248     }                                                                                                    
2249                                                                                                          
2250     protected void onWorkspaceLockedChanged() {                                                          
2251         if (mLauncherCallbacks != null) {                                                                
2252             mLauncherCallbacks.onWorkspaceLockedChanged();                                               
2253         }                                                                                                
2254     }                                                                                                    
2255                                                                                                          
2256     private void resetAddInfo() {                                                                        
2257         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2258         mPendingAddInfo.screenId = -1;                                                                   
2259         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2260         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2261         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2262         mPendingAddInfo.dropPos = null;                                                                  
2263     }                                                                                                    
2264                                                                                                          
2265     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                              
2266             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {          
2267         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2268     }                                                                                                    
2269                                                                                                          
2270     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2271             final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,      
2272             int delay) {                                                                                 
2273         if (appWidgetInfo.configure != null) {                                                           
2274             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2275             mPendingAddWidgetId = appWidgetId;                                                           
2276                                                                                                          
2277             // Launch over to configure widget, if needed                                                
2278             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2279                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2280                                                                                                          
2281         } else {                                                                                         
2282             // Otherwise just add it                                                                     
2283             Runnable onComplete = new Runnable() {                                                       
2284                 @Override                                                                                
2285                 public void run() {                                                                      
2286                     // Exit spring loaded mode if necessary after adding the widget                      
2287                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2288                             null);                                                                       
2289                 }                                                                                        
2290             };                                                                                           
2291             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2292                     appWidgetInfo);                                                                      
2293             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2294         }                                                                                                
2295     }                                                                                                    
2296                                                                                                          
2297     protected void moveToCustomContentScreen(boolean animate) {                                          
2298         // Close any folders that may be open.                                                           
2299         closeFolder();                                                                                   
2300         mWorkspace.moveToCustomContentScreen(animate);                                                   
2301     }                                                                                                    
2302                                                                                                          
2303     public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                   
2304             int[] cell, int spanX, int spanY) {                                                          
2305         switch (info.itemType) {                                                                         
2306             case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                  
2307             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                         
2308                 int span[] = new int[2];                                                                 
2309                 span[0] = spanX;                                                                         
2310                 span[1] = spanY;                                                                         
2311                 addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                        
2312                         container, screenId, cell, span);                                                
2313                 break;                                                                                   
2314             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                          
2315                 processShortcutFromDrop(info.componentName, container, screenId, cell);                  
2316                 break;                                                                                   
2317             default:                                                                                     
2318                 throw new IllegalStateException("Unknown item type: " + info.itemType);                  
2319             }                                                                                            
2320     }                                                                                                    
2321                                                                                                          
2322     /**                                                                                                  
2323      * Process a shortcut drop.                                                                          
2324      *                                                                                                   
2325      * @param componentName The name of the component                                                    
2326      * @param screenId The ID of the screen where it should be added                                     
2327      * @param cell The cell it should be added to, optional                                              
2328      */                                                                                                  
2329     private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,     
2330             int[] cell) {                                                                                
2331         resetAddInfo();                                                                                  
2332         mPendingAddInfo.container = container;                                                           
2333         mPendingAddInfo.screenId = screenId;                                                             
2334         mPendingAddInfo.dropPos = null;                                                                  
2335                                                                                                          
2336         if (cell != null) {                                                                              
2337             mPendingAddInfo.cellX = cell[0];                                                             
2338             mPendingAddInfo.cellY = cell[1];                                                             
2339         }                                                                                                
2340                                                                                                          
2341         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2342         createShortcutIntent.setComponent(componentName);                                                
2343         processShortcut(createShortcutIntent);                                                           
2344     }                                                                                                    
2345                                                                                                          
2346     /**                                                                                                  
2347      * Process a widget drop.                                                                            
2348      *                                                                                                   
2349      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2350      * @param screenId The ID of the screen where it should be added                                     
2351      * @param cell The cell it should be added to, optional                                              
2352      */                                                                                                  
2353     private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,          
2354             int[] cell, int[] span) {                                                                    
2355         resetAddInfo();                                                                                  
2356         mPendingAddInfo.container = info.container = container;                                          
2357         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2358         mPendingAddInfo.dropPos = null;                                                                  
2359         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2360         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2361                                                                                                          
2362         if (cell != null) {                                                                              
2363             mPendingAddInfo.cellX = cell[0];                                                             
2364             mPendingAddInfo.cellY = cell[1];                                                             
2365         }                                                                                                
2366         if (span != null) {                                                                              
2367             mPendingAddInfo.spanX = span[0];                                                             
2368             mPendingAddInfo.spanY = span[1];                                                             
2369         }                                                                                                
2370                                                                                                          
2371         AppWidgetHostView hostView = info.boundWidget;                                                   
2372         int appWidgetId;                                                                                 
2373         if (hostView != null) {                                                                          
2374             appWidgetId = hostView.getAppWidgetId();                                                     
2375             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2376         } else {                                                                                         
2377             // In this case, we either need to start an activity to get permission to bind               
2378             // the widget, or we need to start an activity to configure the widget, or both.             
2379             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2380             Bundle options = info.bindOptions;                                                           
2381                                                                                                          
2382             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2383                     appWidgetId, info.info, options);                                                    
2384             if (success) {                                                                               
2385                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2386             } else {                                                                                     
2387                 mPendingAddWidgetInfo = info.info;                                                       
2388                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2389                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2390                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2391                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2392                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2393                 // TODO: we need to make sure that this accounts for the options bundle.                 
2394                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2395                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2396             }                                                                                            
2397         }                                                                                                
2398     }                                                                                                    
2399                                                                                                          
2400     void processShortcut(Intent intent) {                                                                
2401         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2402     }                                                                                                    
2403                                                                                                          
2404     void processWallpaper(Intent intent) {                                                               
2405         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2406     }                                                                                                    
2407                                                                                                          
2408     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2409             int cellY) {                                                                                 
2410         final FolderInfo folderInfo = new FolderInfo();                                                  
2411         folderInfo.title = getText(R.string.folder_name);                                                
2412                                                                                                          
2413         // Update the model                                                                              
2414         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId,                  
2415                 cellX, cellY);                                                                           
2416         sFolders.put(folderInfo.id, folderInfo);                                                         
2417                                                                                                          
2418         // Create the view                                                                               
2419         FolderIcon newFolder =                                                                           
2420             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2421         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2422                 isWorkspaceLocked());                                                                    
2423         // Force measure the new folder icon                                                             
2424         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2425         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2426         return newFolder;                                                                                
2427     }                                                                                                    
2428                                                                                                          
2429     void removeFolder(FolderInfo folder) {                                                               
2430         sFolders.remove(folder.id);                                                                      
2431     }                                                                                                    
2432                                                                                                          
2433     /**                                                                                                  
2434      * Registers various content observers. The current implementation registers                         
2435      * only a favorites observer to keep track of the favorites applications.                            
2436      */                                                                                                  
2437     private void registerContentObservers() {                                                            
2438         ContentResolver resolver = getContentResolver();                                                 
2439         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2440                 true, mWidgetObserver);                                                                  
2441     }                                                                                                    
2442                                                                                                          
2443     @Override                                                                                            
2444     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2445         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2446             switch (event.getKeyCode()) {                                                                
2447                 case KeyEvent.KEYCODE_HOME:                                                              
2448                     return true;                                                                         
2449                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2450                     if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                              
2451                         dumpState();                                                                     
2452                         return true;                                                                     
2453                     }                                                                                    
2454                     break;                                                                               
2455             }                                                                                            
2456         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2457             switch (event.getKeyCode()) {                                                                
2458                 case KeyEvent.KEYCODE_HOME:                                                              
2459                     return true;                                                                         
2460             }                                                                                            
2461         }                                                                                                
2462                                                                                                          
2463         return super.dispatchKeyEvent(event);                                                            
2464     }                                                                                                    
2465                                                                                                          
2466     @Override                                                                                            
2467     public void onBackPressed() {                                                                        
2468         if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                      
2469             return;                                                                                      
2470         }                                                                                                
2471                                                                                                          
2472         LauncherAccessibilityDelegate delegate =                                                         
2473                 LauncherAppState.getInstance().getAccessibilityDelegate();                               
2474         if (delegate != null && delegate.onBackPressed()) {                                              
2475             return;                                                                                      
2476         }                                                                                                
2477                                                                                                          
2478         if (isAppsViewVisible()) {                                                                       
2479             showWorkspace(true);                                                                         
2480         } else if (isWidgetsViewVisible())  {                                                            
2481             showOverviewMode(true);                                                                      
2482         } else if (mWorkspace.isInOverviewMode()) {                                                      
2483             mWorkspace.exitOverviewMode(true);                                                           
2484         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2485             Folder openFolder = mWorkspace.getOpenFolder();                                              
2486             if (openFolder.isEditingName()) {                                                            
2487                 openFolder.dismissEditingName();                                                         
2488             } else {                                                                                     
2489                 closeFolder();                                                                           
2490             }                                                                                            
2491         } else {                                                                                         
2492             mWorkspace.exitWidgetResizeMode();                                                           
2493                                                                                                          
2494             // Back button is a no-op here, but give at least some feedback for the button press         
2495             mWorkspace.showOutlinesTemporarily();                                                        
2496         }                                                                                                
2497     }                                                                                                    
2498                                                                                                          
2499     /**                                                                                                  
2500      * Re-listen when widgets are reset.                                                                 
2501      */                                                                                                  
2502     @Thunk void onAppWidgetReset() {                                                                     
2503         if (mAppWidgetHost != null) {                                                                    
2504             mAppWidgetHost.startListening();                                                             
2505         }                                                                                                
2506     }                                                                                                    
2507                                                                                                          
2508     /**                                                                                                  
2509      * Launches the intent referred by the clicked shortcut.                                             
2510      *                                                                                                   
2511      * @param v The view representing the clicked shortcut.                                              
2512      */                                                                                                  
2513     public void onClick(View v) {                                                                        
2514         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2515         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2516         if (v.getWindowToken() == null) {                                                                
2517             return;                                                                                      
2518         }                                                                                                
2519                                                                                                          
2520         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2521             return;                                                                                      
2522         }                                                                                                
2523                                                                                                          
2524         if (v instanceof Workspace) {                                                                    
2525             if (mWorkspace.isInOverviewMode()) {                                                         
2526                 mWorkspace.exitOverviewMode(true);                                                       
2527             }                                                                                            
2528             return;                                                                                      
2529         }                                                                                                
2530                                                                                                          
2531         if (v instanceof CellLayout) {                                                                   
2532             if (mWorkspace.isInOverviewMode()) {                                                         
2533                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2534             }                                                                                            
2535         }                                                                                                
2536                                                                                                          
2537         Object tag = v.getTag();                                                                         
2538         if (tag instanceof ShortcutInfo) {                                                               
2539             onClickAppShortcut(v);                                                                       
2540         } else if (tag instanceof FolderInfo) {                                                          
2541             if (v instanceof FolderIcon) {                                                               
2542                 onClickFolderIcon(v);                                                                    
2543             }                                                                                            
2544         } else if (v == mAllAppsButton) {                                                                
2545             onClickAllAppsButton(v);                                                                     
2546         } else if (tag instanceof AppInfo) {                                                             
2547             startAppShortcutOrInfoActivity(v);                                                           
2548         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2549             if (v instanceof PendingAppWidgetHostView) {                                                 
2550                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2551             }                                                                                            
2552         }                                                                                                
2553     }                                                                                                    
2554                                                                                                          
2555     public void onClickPagedViewIcon(View v) {                                                           
2556         startAppShortcutOrInfoActivity(v);                                                               
2557         if (mLauncherCallbacks != null) {                                                                
2558             mLauncherCallbacks.onClickPagedViewIcon(v);                                                  
2559         }                                                                                                
2560     }                                                                                                    
2561                                                                                                          
2562     public boolean onTouch(View v, MotionEvent event) {                                                  
2563         return false;                                                                                    
2564     }                                                                                                    
2565                                                                                                          
2566     /**                                                                                                  
2567      * Event handler for the app widget view which has not fully restored.                               
2568      */                                                                                                  
2569     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2570         if (mIsSafeModeEnabled) {                                                                        
2571             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2572             return;                                                                                      
2573         }                                                                                                
2574                                                                                                          
2575         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2576         if (v.isReadyForClickSetup()) {                                                                  
2577             int widgetId = info.appWidgetId;                                                             
2578             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2579             if (appWidgetInfo != null) {                                                                 
2580                 mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                  
2581                         this, appWidgetInfo);                                                            
2582                 mPendingAddInfo.copyFrom(info);                                                          
2583                 mPendingAddWidgetId = widgetId;                                                          
2584                                                                                                          
2585                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2586                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2587             }                                                                                            
2588         } else if (info.installProgress < 0) {                                                           
2589             // The install has not been queued                                                           
2590             final String packageName = info.providerName.getPackageName();                               
2591             showBrokenAppInstallDialog(packageName,                                                      
2592                 new DialogInterface.OnClickListener() {                                                  
2593                     public void onClick(DialogInterface dialog, int id) {                                
2594                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2595                     }                                                                                    
2596                 });                                                                                      
2597         } else {                                                                                         
2598             // Download has started.                                                                     
2599             final String packageName = info.providerName.getPackageName();                               
2600             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2601         }                                                                                                
2602     }                                                                                                    
2603                                                                                                          
2604     /**                                                                                                  
2605      * Event handler for the "grid" button that appears on the home screen, which                        
2606      * enters all apps mode.                                                                             
2607      *                                                                                                   
2608      * @param v The view that was clicked.                                                               
2609      */                                                                                                  
2610     protected void onClickAllAppsButton(View v) {                                                        
2611         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2612         if (isAppsViewVisible()) {                                                                       
2613             showWorkspace(true);                                                                         
2614         } else {                                                                                         
2615             showAppsView(true /* animated */, false /* resetListToTop */);                               
2616         }                                                                                                
2617     }                                                                                                    
2618                                                                                                          
2619     private void showBrokenAppInstallDialog(final String packageName,                                    
2620             DialogInterface.OnClickListener onSearchClickListener) {                                     
2621         new AlertDialog.Builder(this)                                                                    
2622             .setTitle(R.string.abandoned_promises_title)                                                 
2623             .setMessage(R.string.abandoned_promise_explanation)                                          
2624             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2625             .setNeutralButton(R.string.abandoned_clean_this,                                             
2626                 new DialogInterface.OnClickListener() {                                                  
2627                     public void onClick(DialogInterface dialog, int id) {                                
2628                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2629                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2630                     }                                                                                    
2631                 })                                                                                       
2632             .create().show();                                                                            
2633         return;                                                                                          
2634     }                                                                                                    
2635                                                                                                          
2636     /**                                                                                                  
2637      * Event handler for an app shortcut click.                                                          
2638      *                                                                                                   
2639      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2640      */                                                                                                  
2641     protected void onClickAppShortcut(final View v) {                                                    
2642         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2643         Object tag = v.getTag();                                                                         
2644         if (!(tag instanceof ShortcutInfo)) {                                                            
2645             throw new IllegalArgumentException("Input must be a Shortcut");                              
2646         }                                                                                                
2647                                                                                                          
2648         // Open shortcut                                                                                 
2649         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2650                                                                                                          
2651         if (shortcut.isDisabled != 0) {                                                                  
2652             int error = R.string.activity_not_available;                                                 
2653             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2654                 error = R.string.safemode_shortcut_error;                                                
2655             }                                                                                            
2656             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2657             return;                                                                                      
2658         }                                                                                                
2659                                                                                                          
2660         final Intent intent = shortcut.intent;                                                           
2661                                                                                                          
2662         // Check for special shortcuts                                                                   
2663         if (intent.getComponent() != null) {                                                             
2664             final String shortcutClass = intent.getComponent().getClassName();                           
2665                                                                                                          
2666             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2667                 MemoryDumpActivity.startDump(this);                                                      
2668                 return;                                                                                  
2669             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2670                 toggleShowWeightWatcher();                                                               
2671                 return;                                                                                  
2672             }                                                                                            
2673         }                                                                                                
2674                                                                                                          
2675         // Check for abandoned promise                                                                   
2676         if ((v instanceof BubbleTextView)                                                                
2677                 && shortcut.isPromise()                                                                  
2678                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2679             showBrokenAppInstallDialog(                                                                  
2680                     shortcut.getTargetComponent().getPackageName(),                                      
2681                     new DialogInterface.OnClickListener() {                                              
2682                         public void onClick(DialogInterface dialog, int id) {                            
2683                             startAppShortcutOrInfoActivity(v);                                           
2684                         }                                                                                
2685                     });                                                                                  
2686             return;                                                                                      
2687         }                                                                                                
2688                                                                                                          
2689         // Start activities                                                                              
2690         startAppShortcutOrInfoActivity(v);                                                               
2691                                                                                                          
2692         if (mLauncherCallbacks != null) {                                                                
2693             mLauncherCallbacks.onClickAppShortcut(v);                                                    
2694         }                                                                                                
2695     }                                                                                                    
2696                                                                                                          
2697     @Thunk void startAppShortcutOrInfoActivity(View v) {                                                 
2698         Object tag = v.getTag();                                                                         
2699         final ShortcutInfo shortcut;                                                                     
2700         final Intent intent;                                                                             
2701         if (tag instanceof ShortcutInfo) {                                                               
2702             shortcut = (ShortcutInfo) tag;                                                               
2703             intent = shortcut.intent;                                                                    
2704             int[] pos = new int[2];                                                                      
2705             v.getLocationOnScreen(pos);                                                                  
2706             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2707                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2708                                                                                                          
2709         } else if (tag instanceof AppInfo) {                                                             
2710             shortcut = null;                                                                             
2711             intent = ((AppInfo) tag).intent;                                                             
2712         } else {                                                                                         
2713             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2714         }                                                                                                
2715                                                                                                          
2716         boolean success = startActivitySafely(v, intent, tag);                                           
2717         mStats.recordLaunch(intent, shortcut);                                                           
2718                                                                                                          
2719         if (success && v instanceof BubbleTextView) {                                                    
2720             mWaitingForResume = (BubbleTextView) v;                                                      
2721             mWaitingForResume.setStayPressed(true);                                                      
2722         }                                                                                                
2723     }                                                                                                    
2724                                                                                                          
2725     /**                                                                                                  
2726      * Event handler for a folder icon click.                                                            
2727      *                                                                                                   
2728      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2729      */                                                                                                  
2730     protected void onClickFolderIcon(View v) {                                                           
2731         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2732         if (!(v instanceof FolderIcon)){                                                                 
2733             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2734         }                                                                                                
2735                                                                                                          
2736         FolderIcon folderIcon = (FolderIcon) v;                                                          
2737         final FolderInfo info = folderIcon.getFolderInfo();                                              
2738         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2739                                                                                                          
2740         // If the folder info reports that the associated folder is open, then verify that               
2741         // it is actually opened. There have been a few instances where this gets out of sync.           
2742         if (info.opened && openFolder == null) {                                                         
2743             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2744                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2745             info.opened = false;                                                                         
2746         }                                                                                                
2747                                                                                                          
2748         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2749             // Close any open folder                                                                     
2750             closeFolder();                                                                               
2751             // Open the requested folder                                                                 
2752             openFolder(folderIcon);                                                                      
2753         } else {                                                                                         
2754             // Find the open folder...                                                                   
2755             int folderScreen;                                                                            
2756             if (openFolder != null) {                                                                    
2757                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2758                 // .. and close it                                                                       
2759                 closeFolder(openFolder);                                                                 
2760                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2761                     // Close any folder open on the current screen                                       
2762                     closeFolder();                                                                       
2763                     // Pull the folder onto this screen                                                  
2764                     openFolder(folderIcon);                                                              
2765                 }                                                                                        
2766             }                                                                                            
2767         }                                                                                                
2768                                                                                                          
2769         if (mLauncherCallbacks != null) {                                                                
2770             mLauncherCallbacks.onClickFolderIcon(v);                                                     
2771         }                                                                                                
2772     }                                                                                                    
2773                                                                                                          
2774     /**                                                                                                  
2775      * Event handler for the (Add) Widgets button that appears after a long press                        
2776      * on the home screen.                                                                               
2777      */                                                                                                  
2778     protected void onClickAddWidgetButton(View view) {                                                   
2779         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2780         if (mIsSafeModeEnabled) {                                                                        
2781             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2782         } else {                                                                                         
2783             showWidgetsView(true /* animated */, true /* resetPageToZero */);                            
2784             if (mLauncherCallbacks != null) {                                                            
2785                 mLauncherCallbacks.onClickAddWidgetButton(view);                                         
2786             }                                                                                            
2787         }                                                                                                
2788     }                                                                                                    
2789                                                                                                          
2790     /**                                                                                                  
2791      * Event handler for the wallpaper picker button that appears after a long press                     
2792      * on the home screen.                                                                               
2793      */                                                                                                  
2794     protected void onClickWallpaperPicker(View v) {                                                      
2795         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2796         startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()),     
2797                 REQUEST_PICK_WALLPAPER);                                                                 
2798                                                                                                          
2799         if (mLauncherCallbacks != null) {                                                                
2800             mLauncherCallbacks.onClickWallpaperPicker(v);                                                
2801         }                                                                                                
2802     }                                                                                                    
2803                                                                                                          
2804     /**                                                                                                  
2805      * Event handler for a click on the settings button that appears after a long press                  
2806      * on the home screen.                                                                               
2807      */                                                                                                  
2808     protected void onClickSettingsButton(View v) {                                                       
2809         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2810         if (mLauncherCallbacks != null) {                                                                
2811             mLauncherCallbacks.onClickSettingsButton(v);                                                 
2812         }                                                                                                
2813     }                                                                                                    
2814                                                                                                          
2815     public void onTouchDownAllAppsButton(View v) {                                                       
2816         // Provide the same haptic feedback that the system offers for virtual keys.                     
2817         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2818     }                                                                                                    
2819                                                                                                          
2820     public void performHapticFeedbackOnTouchDown(View v) {                                               
2821         // Provide the same haptic feedback that the system offers for virtual keys.                     
2822         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2823     }                                                                                                    
2824                                                                                                          
2825     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2826         if (mHapticFeedbackTouchListener == null) {                                                      
2827             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2828                 @Override                                                                                
2829                 public boolean onTouch(View v, MotionEvent event) {                                      
2830                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2831                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2832                     }                                                                                    
2833                     return false;                                                                        
2834                 }                                                                                        
2835             };                                                                                           
2836         }                                                                                                
2837         return mHapticFeedbackTouchListener;                                                             
2838     }                                                                                                    
2839                                                                                                          
2840     public void onDragStarted(View view) {                                                               
2841         if (isOnCustomContent()) {                                                                       
2842             // Custom content screen doesn't participate in drag and drop. If on custom                  
2843             // content screen, move to default.                                                          
2844             moveWorkspaceToDefaultScreen();                                                              
2845         }                                                                                                
2846                                                                                                          
2847         if (mLauncherCallbacks != null) {                                                                
2848             mLauncherCallbacks.onDragStarted(view);                                                      
2849         }                                                                                                
2850     }                                                                                                    
2851                                                                                                          
2852     /**                                                                                                  
2853      * Called when the user stops interacting with the launcher.                                         
2854      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2855      */                                                                                                  
2856     protected void onInteractionEnd() {                                                                  
2857         if (mLauncherCallbacks != null) {                                                                
2858             mLauncherCallbacks.onInteractionEnd();                                                       
2859         }                                                                                                
2860     }                                                                                                    
2861                                                                                                          
2862     /**                                                                                                  
2863      * Called when the user starts interacting with the launcher.                                        
2864      * The possible interactions are:                                                                    
2865      *  - open all apps                                                                                  
2866      *  - reorder an app shortcut, or a widget                                                           
2867      *  - open the overview mode.                                                                        
2868      * This is a good time to stop doing things that only make sense                                     
2869      * when the user is on the homescreen and not doing housekeeping.                                    
2870      */                                                                                                  
2871     protected void onInteractionBegin() {                                                                
2872         if (mLauncherCallbacks != null) {                                                                
2873             mLauncherCallbacks.onInteractionBegin();                                                     
2874         }                                                                                                
2875     }                                                                                                    
2876                                                                                                          
2877     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2878         try {                                                                                            
2879             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2880             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2881         } catch (SecurityException e) {                                                                  
2882             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2883             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2884         } catch (ActivityNotFoundException e) {                                                          
2885             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2886             Log.e(TAG, "Unable to launch settings");                                                     
2887         }                                                                                                
2888     }                                                                                                    
2889                                                                                                          
2890     // returns true if the activity was started                                                          
2891     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2892             UserHandleCompat user) {                                                                     
2893         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2894             // System applications cannot be installed. For now, show a toast explaining that.           
2895             // We may give them the option of disabling apps this way.                                   
2896             int messageId = R.string.uninstall_system_app_text;                                          
2897             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2898             return false;                                                                                
2899         } else {                                                                                         
2900             String packageName = componentName.getPackageName();                                         
2901             String className = componentName.getClassName();                                             
2902             Intent intent = new Intent(                                                                  
2903                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2904             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2905                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2906             if (user != null) {                                                                          
2907                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2908             }                                                                                            
2909             startActivity(intent);                                                                       
2910             return true;                                                                                 
2911         }                                                                                                
2912     }                                                                                                    
2913                                                                                                          
2914     boolean startActivity(View v, Intent intent, Object tag) {                                           
2915         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2916         try {                                                                                            
2917             // Only launch using the new animation if the shortcut has not opted out (this is a          
2918             // private contract between launcher and may be ignored in the future).                      
2919             boolean useLaunchAnimation = (v != null) &&                                                  
2920                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2921             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2922             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2923                                                                                                          
2924             UserHandleCompat user = null;                                                                
2925             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2926                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2927                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2928             }                                                                                            
2929                                                                                                          
2930             Bundle optsBundle = null;                                                                    
2931 <<<<<<< GitAnalyzerPlus_ours                                                                             
2932             if (useLaunchAnimation) {                                                                    
2933                 ActivityOptions opts = null;                                                             
2934                 if (sClipRevealMethod != null) {                                                         
2935                     // TODO: call method directly when Launcher3 can depend on M APIs                    
2936                     int left = 0, top = 0;                                                               
2937                     int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();                    
2938                     if (v instanceof TextView) {                                                         
2939                         // Launch from center of icon, not entire view                                   
2940                         Drawable icon = Workspace.getTextViewIcon((TextView) v);                         
2941                         if (icon != null) {                                                              
2942                             Rect bounds = icon.getBounds();                                              
2943                             left = (width - bounds.width()) / 2;                                         
2944                             top = v.getPaddingTop();                                                     
2945                             width = bounds.width();                                                      
2946                             height = bounds.height();                                                    
2947                         }                                                                                
2948                     }                                                                                    
2949                     try {                                                                                
2950                         opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,                       
2951                                 left, top, width, height);                                               
2952                     } catch (IllegalAccessException e) {                                                 
2953                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2954                         sClipRevealMethod = null;                                                        
2955                     } catch (InvocationTargetException e) {                                              
2956                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2957                         sClipRevealMethod = null;                                                        
2958                     }                                                                                    
2959                 }                                                                                        
2960                 if (opts == null && !Utilities.isLmpOrAbove()) {                                         
2961                     opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,                                 
2962                                     v.getMeasuredWidth(), v.getMeasuredHeight());                        
2963                 }                                                                                        
2964                 optsBundle = opts != null ? opts.toBundle() : null;                                      
2965 ||||||| GitAnalyzerPlus_base                                                                             
2966                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2967             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2968             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2969                                                                                                          
2970             UserHandleCompat user = null;                                                                
2971             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2972                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2973                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2974             }                                                                                            
2975                                                                                                          
2976             Bundle optsBundle = null;                                                                    
2977             if (useLaunchAnimation) {                                                                    
2978                 ActivityOptions opts = Utilities.isLmpOrAbove() ?                                        
2979                         ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim)🔵
2980                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
2981                 optsBundle = opts.toBundle();                                                            
2982             }                                                                                            
2983                                                                                                          
2984             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
2985                 // Could be launching some bookkeeping activity                                          
2986                 startActivity(intent, optsBundle);                                                       
2987             } else {                                                                                     
2988                 // TODO Component can be null when shortcuts are supported for secondary user            
2989                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
2990                         intent.getSourceBounds(), optsBundle);                                           
2991             }                                                                                            
2992             return true;                                                                                 
2993         } catch (SecurityException e) {                                                                  
2994             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2995             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
2996                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
2997                     "or use the exported attribute for this activity. "                                  
2998                     + "tag="+ tag + " intent=" + intent, e);                                             
2999 =======                                                                                                  
3000             if (useLaunchAnimation && !Utilities.isLmpOrAbove()) {                                       
3001                 // On pre-L devices, we use the scale up transition.                                     
3002                 // Otherwise we use system default.                                                      
3003                 ActivityOptions opts =                                                                   
3004                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
3005                 optsBundle = opts.toBundle();                                                            
3006 >>>>>>> GitAnalyzerPlus_theirs                                                                           
3007             }                                                                                            
3008                                                                                                          
3009             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
3010                 // Could be launching some bookkeeping activity                                          
3011                 startActivity(intent, optsBundle);                                                       
3012             } else {                                                                                     
3013                 // TODO Component can be null when shortcuts are supported for secondary user            
3014                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
3015                         intent.getSourceBounds(), optsBundle);                                           
3016             }                                                                                            
3017             return true;                                                                                 
3018         } catch (SecurityException e) {                                                                  
3019             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3020             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
3021                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
3022                     "or use the exported attribute for this activity. "                                  
3023                     + "tag="+ tag + " intent=" + intent, e);                                             
3024         }                                                                                                
3025         return false;                                                                                    
3026     }                                                                                                    
3027                                                                                                          
3028     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
3029         boolean success = false;                                                                         
3030         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
3031             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
3032             return false;                                                                                
3033         }                                                                                                
3034         try {                                                                                            
3035             success = startActivity(v, intent, tag);                                                     
3036         } catch (ActivityNotFoundException e) {                                                          
3037             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3038             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
3039         }                                                                                                
3040         return success;                                                                                  
3041     }                                                                                                    
3042                                                                                                          
3043     /**                                                                                                  
3044      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
3045      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
3046      */                                                                                                  
3047     private void copyFolderIconToImage(FolderIcon fi) {                                                  
3048         final int width = fi.getMeasuredWidth();                                                         
3049         final int height = fi.getMeasuredHeight();                                                       
3050                                                                                                          
3051         // Lazy load ImageView, Bitmap and Canvas                                                        
3052         if (mFolderIconImageView == null) {                                                              
3053             mFolderIconImageView = new ImageView(this);                                                  
3054         }                                                                                                
3055         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
3056                 mFolderIconBitmap.getHeight() != height) {                                               
3057             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
3058             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
3059         }                                                                                                
3060                                                                                                          
3061         DragLayer.LayoutParams lp;                                                                       
3062         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
3063             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
3064         } else {                                                                                         
3065             lp = new DragLayer.LayoutParams(width, height);                                              
3066         }                                                                                                
3067                                                                                                          
3068         // The layout from which the folder is being opened may be scaled, adjust the starting           
3069         // view size by this scale factor.                                                               
3070         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
3071         lp.customPosition = true;                                                                        
3072         lp.x = mRectForFolderAnimation.left;                                                             
3073         lp.y = mRectForFolderAnimation.top;                                                              
3074         lp.width = (int) (scale * width);                                                                
3075         lp.height = (int) (scale * height);                                                              
3076                                                                                                          
3077         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
3078         fi.draw(mFolderIconCanvas);                                                                      
3079         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
3080         if (fi.getFolder() != null) {                                                                    
3081             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
3082             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
3083         }                                                                                                
3084         // Just in case this image view is still in the drag layer from a previous animation,            
3085         // we remove it and re-add it.                                                                   
3086         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3087             mDragLayer.removeView(mFolderIconImageView);                                                 
3088         }                                                                                                
3089         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3090         if (fi.getFolder() != null) {                                                                    
3091             fi.getFolder().bringToFront();                                                               
3092         }                                                                                                
3093     }                                                                                                    
3094                                                                                                          
3095     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3096         if (fi == null) return;                                                                          
3097         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3098         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3099         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3100                                                                                                          
3101         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3102         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3103             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3104             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3105             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3106         }                                                                                                
3107                                                                                                          
3108         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3109         copyFolderIconToImage(fi);                                                                       
3110         fi.setVisibility(View.INVISIBLE);                                                                
3111                                                                                                          
3112         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3113                 scaleX, scaleY);                                                                         
3114         if (Utilities.isLmpOrAbove()) {                                                                  
3115             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3116         }                                                                                                
3117         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3118         oa.start();                                                                                      
3119     }                                                                                                    
3120                                                                                                          
3121     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3122         if (fi == null) return;                                                                          
3123         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3124         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3125         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3126                                                                                                          
3127         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3128                                                                                                          
3129         // We remove and re-draw the FolderIcon in-case it has changed                                   
3130         mDragLayer.removeView(mFolderIconImageView);                                                     
3131         copyFolderIconToImage(fi);                                                                       
3132         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3133                 scaleX, scaleY);                                                                         
3134         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3135         oa.addListener(new AnimatorListenerAdapter() {                                                   
3136             @Override                                                                                    
3137             public void onAnimationEnd(Animator animation) {                                             
3138                 if (cl != null) {                                                                        
3139                     cl.clearFolderLeaveBehind();                                                         
3140                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3141                     mDragLayer.removeView(mFolderIconImageView);                                         
3142                     fi.setVisibility(View.VISIBLE);                                                      
3143                 }                                                                                        
3144             }                                                                                            
3145         });                                                                                              
3146         oa.start();                                                                                      
3147     }                                                                                                    
3148                                                                                                          
3149     /**                                                                                                  
3150      * Opens the user folder described by the specified tag. The opening of the folder                   
3151      * is animated relative to the specified View. If the View is null, no animation                     
3152      * is played.                                                                                        
3153      *                                                                                                   
3154      * @param folderInfo The FolderInfo describing the folder to open.                                   
3155      */                                                                                                  
3156     public void openFolder(FolderIcon folderIcon) {                                                      
3157         Folder folder = folderIcon.getFolder();                                                          
3158         Folder openFolder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                      
3159         if (openFolder != null && openFolder != folder) {                                                
3160             // Close any open folder before opening a folder.                                            
3161             closeFolder();                                                                               
3162         }                                                                                                
3163                                                                                                          
3164         FolderInfo info = folder.mInfo;                                                                  
3165                                                                                                          
3166         info.opened = true;                                                                              
3167                                                                                                          
3168         // While the folder is open, the position of the icon cannot change.                             
3169         ((CellLayout.LayoutParams) folderIcon.getLayoutParams()).canReorder = false;                     
3170                                                                                                          
3171         // Just verify that the folder hasn't already been added to the DragLayer.                       
3172         // There was a one-off crash where the folder had a parent already.                              
3173         if (folder.getParent() == null) {                                                                
3174             mDragLayer.addView(folder);                                                                  
3175             mDragController.addDropTarget((DropTarget) folder);                                          
3176         } else {                                                                                         
3177             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3178                     folder.getParent() + ").");                                                          
3179         }                                                                                                
3180         folder.animateOpen();                                                                            
3181         growAndFadeOutFolderIcon(folderIcon);                                                            
3182                                                                                                          
3183         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3184         // the workspace items                                                                           
3185         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3186         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3187     }                                                                                                    
3188                                                                                                          
3189     public void closeFolder() {                                                                          
3190         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3191         if (folder != null) {                                                                            
3192             if (folder.isEditingName()) {                                                                
3193                 folder.dismissEditingName();                                                             
3194             }                                                                                            
3195             closeFolder(folder);                                                                         
3196         }                                                                                                
3197     }                                                                                                    
3198                                                                                                          
3199     void closeFolder(Folder folder) {                                                                    
3200         folder.getInfo().opened = false;                                                                 
3201                                                                                                          
3202         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3203         if (parent != null) {                                                                            
3204             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3205             shrinkAndFadeInFolderIcon(fi);                                                               
3206             if (fi != null) {                                                                            
3207                 ((CellLayout.LayoutParams) fi.getLayoutParams()).canReorder = true;                      
3208             }                                                                                            
3209         }                                                                                                
3210         folder.animateClosed();                                                                          
3211                                                                                                          
3212         // Notify the accessibility manager that this folder "window" has disappeard and no              
3213         // longer occludeds the workspace items                                                          
3214         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3215     }                                                                                                    
3216                                                                                                          
3217     public boolean onLongClick(View v) {                                                                 
3218         if (!isDraggingEnabled()) return false;                                                          
3219         if (isWorkspaceLocked()) return false;                                                           
3220         if (mState != State.WORKSPACE) return false;                                                     
3221                                                                                                          
3222         if (v instanceof Workspace) {                                                                    
3223             if (!mWorkspace.isInOverviewMode()) {                                                        
3224                 if (mWorkspace.enterOverviewMode()) {                                                    
3225                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3226                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3227                     return true;                                                                         
3228                 } else {                                                                                 
3229                     return false;                                                                        
3230                 }                                                                                        
3231             } else {                                                                                     
3232                 return false;                                                                            
3233             }                                                                                            
3234         }                                                                                                
3235                                                                                                          
3236         CellLayout.CellInfo longClickCellInfo = null;                                                    
3237         View itemUnderLongClick = null;                                                                  
3238         if (v.getTag() instanceof ItemInfo) {                                                            
3239             ItemInfo info = (ItemInfo) v.getTag();                                                       
3240             longClickCellInfo = new CellLayout.CellInfo(v, info);                                        
3241             itemUnderLongClick = longClickCellInfo.cell;                                                 
3242             resetAddInfo();                                                                              
3243         }                                                                                                
3244                                                                                                          
3245         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3246         // on hotseat items.                                                                             
3247         final boolean inHotseat = isHotseatLayout(v);                                                    
3248         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3249         if (allowLongPress && !mDragController.isDragging()) {                                           
3250             if (itemUnderLongClick == null) {                                                            
3251                 // User long pressed on empty space                                                      
3252                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3253                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3254                 if (mWorkspace.isInOverviewMode()) {                                                     
3255                     mWorkspace.startReordering(v);                                                       
3256                 } else {                                                                                 
3257                     mWorkspace.enterOverviewMode();                                                      
3258                 }                                                                                        
3259             } else {                                                                                     
3260                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3261                         mHotseat.getOrderInHotseat(                                                      
3262                                 longClickCellInfo.cellX,                                                 
3263                                 longClickCellInfo.cellY));                                               
3264                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3265                     // User long pressed on an item                                                      
3266                     mWorkspace.startDrag(longClickCellInfo);                                             
3267                 }                                                                                        
3268             }                                                                                            
3269         }                                                                                                
3270         return true;                                                                                     
3271     }                                                                                                    
3272                                                                                                          
3273     boolean isHotseatLayout(View layout) {                                                               
3274         return mHotseat != null && layout != null &&                                                     
3275                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3276     }                                                                                                    
3277                                                                                                          
3278     /**                                                                                                  
3279      * Returns the CellLayout of the specified container at the specified screen.                        
3280      */                                                                                                  
3281     public CellLayout getCellLayout(long container, long screenId) {                                     
3282         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3283             if (mHotseat != null) {                                                                      
3284                 return mHotseat.getLayout();                                                             
3285             } else {                                                                                     
3286                 return null;                                                                             
3287             }                                                                                            
3288         } else {                                                                                         
3289             return mWorkspace.getScreenWithId(screenId);                                                 
3290         }                                                                                                
3291     }                                                                                                    
3292                                                                                                          
3293     /**                                                                                                  
3294      * For overridden classes.                                                                           
3295      */                                                                                                  
3296     public boolean isAllAppsVisible() {                                                                  
3297         return isAppsViewVisible();                                                                      
3298     }                                                                                                    
3299                                                                                                          
3300     public boolean isAppsViewVisible() {                                                                 
3301         return (mState == State.APPS) || (mOnResumeState == State.APPS);                                 
3302     }                                                                                                    
3303                                                                                                          
3304     public boolean isWidgetsViewVisible() {                                                              
3305         return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                           
3306     }                                                                                                    
3307                                                                                                          
3308     private void setWorkspaceBackground(boolean workspace) {                                             
3309         mLauncherView.setBackground(workspace ?                                                          
3310                 mWorkspaceBackgroundDrawable : null);                                                    
3311     }                                                                                                    
3312                                                                                                          
3313     protected void changeWallpaperVisiblity(boolean visible) {                                           
3314         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3315         int curflags = getWindow().getAttributes().flags                                                 
3316                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3317         if (wpflags != curflags) {                                                                       
3318             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3319         }                                                                                                
3320         setWorkspaceBackground(visible);                                                                 
3321     }                                                                                                    
3322                                                                                                          
3323     @Override                                                                                            
3324     public void onTrimMemory(int level) {                                                                
3325         super.onTrimMemory(level);                                                                       
3326         if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                        
3327             // The widget preview db can result in holding onto over                                     
3328             // 3MB of memory for caching which isn't necessary.                                          
3329             SQLiteDatabase.releaseMemory();                                                              
3330                                                                                                          
3331             // This clears all widget bitmaps from the widget tray                                       
3332             // TODO(hyunyoungs)                                                                          
3333         }                                                                                                
3334         if (mLauncherCallbacks != null) {                                                                
3335             mLauncherCallbacks.onTrimMemory(level);                                                      
3336         }                                                                                                
3337     }                                                                                                    
3338                                                                                                          
3339     @Override                                                                                            
3340     public void onStateTransitionHideSearchBar() {                                                       
3341         // Hide the search bar                                                                           
3342         if (mSearchDropTargetBar != null) {                                                              
3343             mSearchDropTargetBar.hideSearchBar(false /* animated */);                                    
3344         }                                                                                                
3345     }                                                                                                    
3346                                                                                                          
3347     protected void showWorkspace(boolean animated) {                                                     
3348         showWorkspace(animated, null);                                                                   
3349     }                                                                                                    
3350                                                                                                          
3351     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3352         boolean changed = mState != State.WORKSPACE ||                                                   
3353                 mWorkspace.getState() != Workspace.State.NORMAL;                                         
3354         if (changed) {                                                                                   
3355             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3356             mWorkspace.setVisibility(View.VISIBLE);                                                      
3357             mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,          
3358                     animated, onCompleteRunnable);                                                       
3359                                                                                                          
3360             // Show the search bar (only animate if we were showing the drop target bar in spring        
3361             // loaded mode)                                                                              
3362             if (mSearchDropTargetBar != null) {                                                          
3363                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3364             }                                                                                            
3365                                                                                                          
3366             // Set focus to the AppsCustomize button                                                     
3367             if (mAllAppsButton != null) {                                                                
3368                 mAllAppsButton.requestFocus();                                                           
3369             }                                                                                            
3370         }                                                                                                
3371                                                                                                          
3372         // Change the state *after* we've called all the transition code                                 
3373         mState = State.WORKSPACE;                                                                        
3374                                                                                                          
3375         // Resume the auto-advance of widgets                                                            
3376         mUserPresent = true;                                                                             
3377         updateAutoAdvanceState();                                                                        
3378                                                                                                          
3379         if (changed) {                                                                                   
3380             // Send an accessibility event to announce the context change                                
3381             getWindow().getDecorView()                                                                   
3382                     .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);               
3383                                                                                                          
3384             onWorkspaceShown(animated);                                                                  
3385         }                                                                                                
3386     }                                                                                                    
3387                                                                                                          
3388     void showOverviewMode(boolean animated) {                                                            
3389         mWorkspace.setVisibility(View.VISIBLE);                                                          
3390         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,            
3391                 animated, null /* onCompleteRunnable */);                                                
3392         mState = State.WORKSPACE;                                                                        
3393         onWorkspaceShown(animated);                                                                      
3394     }                                                                                                    
3395                                                                                                          
3396     public void onWorkspaceShown(boolean animated) {                                                     
3397     }                                                                                                    
3398                                                                                                          
3399     /**                                                                                                  
3400      * Shows the apps view.                                                                              
3401      */                                                                                                  
3402     void showAppsView(boolean animated, boolean resetListToTop) {                                        
3403         if (resetListToTop) {                                                                            
3404             mAppsView.scrollToTop();                                                                     
3405         }                                                                                                
3406         showAppsOrWidgets(animated, State.APPS);                                                         
3407     }                                                                                                    
3408                                                                                                          
3409     /**                                                                                                  
3410      * Shows the widgets view.                                                                           
3411      */                                                                                                  
3412     void showWidgetsView(boolean animated, boolean resetPageToZero) {                                    
3413         Log.d(TAG, "showWidgetsView:" + animated + " resetPageToZero:" + resetPageToZero);               
3414         if (resetPageToZero) {                                                                           
3415             mWidgetsView.scrollToTop();                                                                  
3416         }                                                                                                
3417         showAppsOrWidgets(animated, State.WIDGETS);                                                      
3418                                                                                                          
3419         mWidgetsView.post(new Runnable() {                                                               
3420             @Override                                                                                    
3421             public void run() {                                                                          
3422                 mWidgetsView.requestFocus();                                                             
3423             }                                                                                            
3424         });                                                                                              
3425     }                                                                                                    
3426                                                                                                          
3427     /**                                                                                                  
3428      * Sets up the transition to show the apps/widgets view.                                             
3429      */                                                                                                  
3430     private void showAppsOrWidgets(boolean animated, State toState) {                                    
3431         if (mState != State.WORKSPACE) return;                                                           
3432         if (toState != State.APPS && toState != State.WIDGETS) return;                                   
3433                                                                                                          
3434         if (toState == State.APPS) {                                                                     
3435             mStateTransitionAnimation.startAnimationToAllApps(animated);                                 
3436             if (mLauncherCallbacks != null) {                                                            
3437                 mLauncherCallbacks.onAllAppsShown();                                                     
3438             }                                                                                            
3439         } else {                                                                                         
3440             mStateTransitionAnimation.startAnimationToWidgets(animated);                                 
3441         }                                                                                                
3442                                                                                                          
3443         // Change the state *after* we've called all the transition code                                 
3444         mState = toState;                                                                                
3445                                                                                                          
3446         // Pause the auto-advance of widgets until we are out of AllApps                                 
3447         mUserPresent = false;                                                                            
3448         updateAutoAdvanceState();                                                                        
3449         closeFolder();                                                                                   
3450                                                                                                          
3451         // Send an accessibility event to announce the context change                                    
3452         getWindow().getDecorView()                                                                       
3453                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3454     }                                                                                                    
3455                                                                                                          
3456     public void enterSpringLoadedDragMode() {                                                            
3457         Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s",                                 
3458                 mState.name()));                                                                         
3459         if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||                           
3460                 mState == State.WIDGETS_SPRING_LOADED) {                                                 
3461             return;                                                                                      
3462         }                                                                                                
3463                                                                                                          
3464         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,       
3465                 true /* animated */, null /* onCompleteRunnable */);                                     
3466         mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;           
3467     }                                                                                                    
3468                                                                                                          
3469     public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                 
3470             final Runnable onCompleteRunnable) {                                                         
3471         if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;         
3472                                                                                                          
3473         mHandler.postDelayed(new Runnable() {                                                            
3474             @Override                                                                                    
3475             public void run() {                                                                          
3476                 if (successfulDrop) {                                                                    
3477                     // TODO(hyunyoungs): verify if this hack is still needed, if not, delete.            
3478                     //                                                                                   
3479                     // Before we show workspace, hide all apps again because                             
3480                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3481                     // clean up our state transition functions                                           
3482                     mWidgetsView.setVisibility(View.GONE);                                               
3483                     showWorkspace(true, onCompleteRunnable);                                             
3484                 } else {                                                                                 
3485                     exitSpringLoadedDragMode();                                                          
3486                 }                                                                                        
3487             }                                                                                            
3488         }, delay);                                                                                       
3489     }                                                                                                    
3490                                                                                                          
3491     void exitSpringLoadedDragMode() {                                                                    
3492         if (mState == State.APPS_SPRING_LOADED) {                                                        
3493             mStateTransitionAnimation.startAnimationToAllApps(true /* animated */);                      
3494             mState = State.APPS;                                                                         
3495         } else if (mState == State.WIDGETS_SPRING_LOADED) {                                              
3496             mStateTransitionAnimation.startAnimationToWidgets(true /* animated */);                      
3497             mState = State.WIDGETS;                                                                      
3498         }                                                                                                
3499         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3500     }                                                                                                    
3501                                                                                                          
3502     void lockAllApps() {                                                                                 
3503         // TODO                                                                                          
3504     }                                                                                                    
3505                                                                                                          
3506     void unlockAllApps() {                                                                               
3507         // TODO                                                                                          
3508     }                                                                                                    
3509                                                                                                          
3510     protected void disableVoiceButtonProxy(boolean disable) {                                            
3511         // NO-OP                                                                                         
3512     }                                                                                                    
3513                                                                                                          
3514     public View getOrCreateQsbBar() {                                                                    
3515         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
3516             return mLauncherCallbacks.getQsbBar();                                                       
3517         }                                                                                                
3518                                                                                                          
3519         if (mQsb == null) {                                                                              
3520             AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);              
3521             if (searchProvider == null) {                                                                
3522                 return null;                                                                             
3523             }                                                                                            
3524                                                                                                          
3525             Bundle opts = new Bundle();                                                                  
3526             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                 
3527                     AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                    
3528                                                                                                          
3529             SharedPreferences sp = getSharedPreferences(                                                 
3530                     LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                           
3531             int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                 
3532             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);             
3533             if (!searchProvider.provider.flattenToString().equals(                                       
3534                     sp.getString(QSB_WIDGET_PROVIDER, null))                                             
3535                     || (widgetInfo == null)                                                              
3536                     || !widgetInfo.provider.equals(searchProvider.provider)) {                           
3537                 // A valid widget is not already bound.                                                  
3538                 if (widgetId > -1) {                                                                     
3539                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3540                     widgetId = -1;                                                                       
3541                 }                                                                                        
3542                                                                                                          
3543                 // Try to bind a new widget                                                              
3544                 widgetId = mAppWidgetHost.allocateAppWidgetId();                                         
3545                                                                                                          
3546                 if (!AppWidgetManagerCompat.getInstance(this)                                            
3547                         .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                     
3548                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3549                     widgetId = -1;                                                                       
3550                 }                                                                                        
3551                                                                                                          
3552                 sp.edit()                                                                                
3553                     .putInt(QSB_WIDGET_ID, widgetId)                                                     
3554                     .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())           
3555                     .commit();                                                                           
3556             }                                                                                            
3557                                                                                                          
3558             if (widgetId != -1) {                                                                        
3559                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                        
3560                 mQsb.updateAppWidgetOptions(opts);                                                       
3561                 mQsb.setPadding(0, 0, 0, 0);                                                             
3562                 mSearchDropTargetBar.addView(mQsb);                                                      
3563                 mSearchDropTargetBar.setQsbSearchBar(mQsb);                                              
3564             }                                                                                            
3565         }                                                                                                
3566         return mQsb;                                                                                     
3567     }                                                                                                    
3568                                                                                                          
3569     private void reinflateQSBIfNecessary() {                                                             
3570         if (mQsb instanceof LauncherAppWidgetHostView &&                                                 
3571                 ((LauncherAppWidgetHostView) mQsb).isReinflateRequired()) {                              
3572             mSearchDropTargetBar.removeView(mQsb);                                                       
3573             mQsb = null;                                                                                 
3574             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
3575         }                                                                                                
3576     }                                                                                                    
3577                                                                                                          
3578     @Override                                                                                            
3579     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3580         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3581         final List<CharSequence> text = event.getText();                                                 
3582         text.clear();                                                                                    
3583         // Populate event with a fake title based on the current state.                                  
3584         if (mState == State.APPS) {                                                                      
3585             text.add("Apps");                                                                            
3586         } else if (mState == State.WIDGETS) {                                                            
3587             text.add("Widgets");                                                                         
3588         } else {                                                                                         
3589             text.add(getString(R.string.all_apps_home_button_label));                                    
3590         }                                                                                                
3591         return result;                                                                                   
3592     }                                                                                                    
3593                                                                                                          
3594     /**                                                                                                  
3595      * Receives notifications when system dialogs are to be closed.                                      
3596      */                                                                                                  
3597     @Thunk class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                            
3598         @Override                                                                                        
3599         public void onReceive(Context context, Intent intent) {                                          
3600             closeSystemDialogs();                                                                        
3601         }                                                                                                
3602     }                                                                                                    
3603                                                                                                          
3604     /**                                                                                                  
3605      * Receives notifications whenever the appwidgets are reset.                                         
3606      */                                                                                                  
3607     private class AppWidgetResetObserver extends ContentObserver {                                       
3608         public AppWidgetResetObserver() {                                                                
3609             super(new Handler());                                                                        
3610         }                                                                                                
3611                                                                                                          
3612         @Override                                                                                        
3613         public void onChange(boolean selfChange) {                                                       
3614             onAppWidgetReset();                                                                          
3615         }                                                                                                
3616     }                                                                                                    
3617                                                                                                          
3618     /**                                                                                                  
3619      * If the activity is currently paused, signal that we need to run the passed Runnable               
3620      * in onResume.                                                                                      
3621      *                                                                                                   
3622      * This needs to be called from incoming places where resources might have been loaded               
3623      * while we are paused.  That is becaues the Configuration might be wrong                            
3624      * when we're not running, and if it comes back to what it was when we                               
3625      * were paused, we are not restarted.                                                                
3626      *                                                                                                   
3627      * Implementation of the method from LauncherModel.Callbacks.                                        
3628      *                                                                                                   
3629      * @return true if we are currently paused.  The caller might be able to                             
3630      * skip some work in that case since we will come back again.                                        
3631      */                                                                                                  
3632     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3633         if (mPaused) {                                                                                   
3634             Log.i(TAG, "Deferring update until onResume");                                               
3635             if (deletePreviousRunnables) {                                                               
3636                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3637                 }                                                                                        
3638             }                                                                                            
3639             mBindOnResumeCallbacks.add(run);                                                             
3640             return true;                                                                                 
3641         } else {                                                                                         
3642             return false;                                                                                
3643         }                                                                                                
3644     }                                                                                                    
3645                                                                                                          
3646     private boolean waitUntilResume(Runnable run) {                                                      
3647         return waitUntilResume(run, false);                                                              
3648     }                                                                                                    
3649                                                                                                          
3650     public void addOnResumeCallback(Runnable run) {                                                      
3651         mOnResumeCallbacks.add(run);                                                                     
3652     }                                                                                                    
3653                                                                                                          
3654     /**                                                                                                  
3655      * If the activity is currently paused, signal that we need to re-run the loader                     
3656      * in onResume.                                                                                      
3657      *                                                                                                   
3658      * This needs to be called from incoming places where resources might have been loaded               
3659      * while we are paused.  That is becaues the Configuration might be wrong                            
3660      * when we're not running, and if it comes back to what it was when we                               
3661      * were paused, we are not restarted.                                                                
3662      *                                                                                                   
3663      * Implementation of the method from LauncherModel.Callbacks.                                        
3664      *                                                                                                   
3665      * @return true if we are currently paused.  The caller might be able to                             
3666      * skip some work in that case since we will come back again.                                        
3667      */                                                                                                  
3668     public boolean setLoadOnResume() {                                                                   
3669         if (mPaused) {                                                                                   
3670             Log.i(TAG, "setLoadOnResume");                                                               
3671             mOnResumeNeedsLoad = true;                                                                   
3672             return true;                                                                                 
3673         } else {                                                                                         
3674             return false;                                                                                
3675         }                                                                                                
3676     }                                                                                                    
3677                                                                                                          
3678     /**                                                                                                  
3679      * Implementation of the method from LauncherModel.Callbacks.                                        
3680      */                                                                                                  
3681     public int getCurrentWorkspaceScreen() {                                                             
3682         if (mWorkspace != null) {                                                                        
3683             return mWorkspace.getCurrentPage();                                                          
3684         } else {                                                                                         
3685             return SCREEN_COUNT / 2;                                                                     
3686         }                                                                                                
3687     }                                                                                                    
3688                                                                                                          
3689     /**                                                                                                  
3690      * Refreshes the shortcuts shown on the workspace.                                                   
3691      *                                                                                                   
3692      * Implementation of the method from LauncherModel.Callbacks.                                        
3693      */                                                                                                  
3694     public void startBinding() {                                                                         
3695         setWorkspaceLoading(true);                                                                       
3696                                                                                                          
3697         // If we're starting binding all over again, clear any bind calls we'd postponed in              
3698         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
3699         // from scratch again                                                                            
3700         mBindOnResumeCallbacks.clear();                                                                  
3701                                                                                                          
3702         // Clear the workspace because it's going to be rebound                                          
3703         mWorkspace.clearDropTargets();                                                                   
3704         mWorkspace.removeAllWorkspaceScreens();                                                          
3705                                                                                                          
3706         mWidgetsToAdvance.clear();                                                                       
3707         if (mHotseat != null) {                                                                          
3708             mHotseat.resetLayout();                                                                      
3709         }                                                                                                
3710     }                                                                                                    
3711                                                                                                          
3712     @Override                                                                                            
3713     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
3714         bindAddScreens(orderedScreenIds);                                                                
3715                                                                                                          
3716         // If there are no screens, we need to have an empty screen                                      
3717         if (orderedScreenIds.size() == 0) {                                                              
3718             mWorkspace.addExtraEmptyScreen();                                                            
3719         }                                                                                                
3720                                                                                                          
3721         // Create the custom content page (this call updates mDefaultScreen which calls                  
3722         // setCurrentPage() so ensure that all pages are added before calling this).                     
3723         if (hasCustomContentToLeft()) {                                                                  
3724             mWorkspace.createCustomContentContainer();                                                   
3725             populateCustomContentContainer();                                                            
3726         }                                                                                                
3727     }                                                                                                    
3728                                                                                                          
3729     @Override                                                                                            
3730     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
3731         // Log to disk                                                                                   
3732         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
3733         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
3734                 TextUtils.join(", ", orderedScreenIds), true);                                           
3735         int count = orderedScreenIds.size();                                                             
3736         for (int i = 0; i < count; i++) {                                                                
3737             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
3738         }                                                                                                
3739     }                                                                                                    
3740                                                                                                          
3741     @Override                                                                                            
3742     public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                  
3743             final long screenId, final int[] cell, final int spanX, final int spanY) {                   
3744         showWorkspace(true, new Runnable() {                                                             
3745                                                                                                          
3746             @Override                                                                                    
3747             public void run() {                                                                          
3748                 mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                     
3749                 addPendingItem(info, container, screenId, cell, spanX, spanY);                           
3750             }                                                                                            
3751         });                                                                                              
3752     }                                                                                                    
3753                                                                                                          
3754     private boolean shouldShowWeightWatcher() {                                                          
3755         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3756         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3757         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
3758                                                                                                          
3759         return show;                                                                                     
3760     }                                                                                                    
3761                                                                                                          
3762     private void toggleShowWeightWatcher() {                                                             
3763         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3764         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3765         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
3766                                                                                                          
3767         show = !show;                                                                                    
3768                                                                                                          
3769         SharedPreferences.Editor editor = sp.edit();                                                     
3770         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
3771         editor.commit();                                                                                 
3772                                                                                                          
3773         if (mWeightWatcher != null) {                                                                    
3774             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
3775         }                                                                                                
3776     }                                                                                                    
3777                                                                                                          
3778     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
3779                               final ArrayList<ItemInfo> addNotAnimated,                                  
3780                               final ArrayList<ItemInfo> addAnimated,                                     
3781                               final ArrayList<AppInfo> addedApps) {                                      
3782         Runnable r = new Runnable() {                                                                    
3783             public void run() {                                                                          
3784                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
3785             }                                                                                            
3786         };                                                                                               
3787         if (waitUntilResume(r)) {                                                                        
3788             return;                                                                                      
3789         }                                                                                                
3790                                                                                                          
3791         // Add the new screens                                                                           
3792         if (newScreens != null) {                                                                        
3793             bindAddScreens(newScreens);                                                                  
3794         }                                                                                                
3795                                                                                                          
3796         // We add the items without animation on non-visible pages, and with                             
3797         // animations on the new page (which we will try and snap to).                                   
3798         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
3799             bindItems(addNotAnimated, 0,                                                                 
3800                     addNotAnimated.size(), false);                                                       
3801         }                                                                                                
3802         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
3803             bindItems(addAnimated, 0,                                                                    
3804                     addAnimated.size(), true);                                                           
3805         }                                                                                                
3806                                                                                                          
3807         // Remove the extra empty screen                                                                 
3808         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
3809                                                                                                          
3810         if (addedApps != null && mAppsView != null) {                                                    
3811             mAppsView.addApps(addedApps);                                                                
3812         }                                                                                                
3813     }                                                                                                    
3814                                                                                                          
3815     /**                                                                                                  
3816      * Bind the items start-end from the list.                                                           
3817      *                                                                                                   
3818      * Implementation of the method from LauncherModel.Callbacks.                                        
3819      */                                                                                                  
3820     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
3821                           final boolean forceAnimateIcons) {                                             
3822         Runnable r = new Runnable() {                                                                    
3823             public void run() {                                                                          
3824                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
3825             }                                                                                            
3826         };                                                                                               
3827         if (waitUntilResume(r)) {                                                                        
3828             return;                                                                                      
3829         }                                                                                                
3830                                                                                                          
3831         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
3832         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
3833         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
3834         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
3835         Workspace workspace = mWorkspace;                                                                
3836         long newShortcutsScreenId = -1;                                                                  
3837         for (int i = start; i < end; i++) {                                                              
3838             final ItemInfo item = shortcuts.get(i);                                                      
3839                                                                                                          
3840             // Short circuit if we are loading dock items for a configuration which has no dock          
3841             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
3842                     mHotseat == null) {                                                                  
3843                 continue;                                                                                
3844             }                                                                                            
3845                                                                                                          
3846             switch (item.itemType) {                                                                     
3847                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
3848                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
3849                     ShortcutInfo info = (ShortcutInfo) item;                                             
3850                     View shortcut = createShortcut(info);                                                
3851                                                                                                          
3852                     /*                                                                                   
3853                      * TODO: FIX collision case                                                          
3854                      */                                                                                  
3855                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
3856                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
3857                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
3858                             View v = cl.getChildAt(item.cellX, item.cellY);                              
3859                             Object tag = v.getTag();                                                     
3860                             String desc = "Collision while binding workspace item: " + item              
3861                                     + ". Collides with " + tag;                                          
3862                             if (LauncherAppState.isDogfoodBuild()) {                                     
3863                                 throw (new RuntimeException(desc));                                      
3864                             } else {                                                                     
3865                                 Log.d(TAG, desc);                                                        
3866                             }                                                                            
3867                         }                                                                                
3868                     }                                                                                    
3869                                                                                                          
3870                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
3871                             item.cellY, 1, 1);                                                           
3872                     if (animateIcons) {                                                                  
3873                         // Animate all the applications up now                                           
3874                         shortcut.setAlpha(0f);                                                           
3875                         shortcut.setScaleX(0f);                                                          
3876                         shortcut.setScaleY(0f);                                                          
3877                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
3878                         newShortcutsScreenId = item.screenId;                                            
3879                     }                                                                                    
3880                     break;                                                                               
3881                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
3882                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
3883                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
3884                             (FolderInfo) item, mIconCache);                                              
3885                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
3886                             item.cellY, 1, 1);                                                           
3887                     break;                                                                               
3888                 default:                                                                                 
3889                     throw new RuntimeException("Invalid Item Type");                                     
3890             }                                                                                            
3891         }                                                                                                
3892                                                                                                          
3893         if (animateIcons) {                                                                              
3894             // Animate to the correct page                                                               
3895             if (newShortcutsScreenId > -1) {                                                             
3896                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
3897                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
3898                 final Runnable startBounceAnimRunnable = new Runnable() {                                
3899                     public void run() {                                                                  
3900                         anim.playTogether(bounceAnims);                                                  
3901                         anim.start();                                                                    
3902                     }                                                                                    
3903                 };                                                                                       
3904                 if (newShortcutsScreenId != currentScreenId) {                                           
3905                     // We post the animation slightly delayed to prevent slowdowns                       
3906                     // when we are loading right after we return to launcher.                            
3907                     mWorkspace.postDelayed(new Runnable() {                                              
3908                         public void run() {                                                              
3909                             if (mWorkspace != null) {                                                    
3910                                 mWorkspace.snapToPage(newScreenIndex);                                   
3911                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
3912                                         NEW_APPS_ANIMATION_DELAY);                                       
3913                             }                                                                            
3914                         }                                                                                
3915                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
3916                 } else {                                                                                 
3917                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
3918                 }                                                                                        
3919             }                                                                                            
3920         }                                                                                                
3921         workspace.requestLayout();                                                                       
3922     }                                                                                                    
3923                                                                                                          
3924     /**                                                                                                  
3925      * Implementation of the method from LauncherModel.Callbacks.                                        
3926      */                                                                                                  
3927     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
3928         Runnable r = new Runnable() {                                                                    
3929             public void run() {                                                                          
3930                 bindFolders(folders);                                                                    
3931             }                                                                                            
3932         };                                                                                               
3933         if (waitUntilResume(r)) {                                                                        
3934             return;                                                                                      
3935         }                                                                                                
3936         sFolders.clear();                                                                                
3937         sFolders.putAll(folders);                                                                        
3938     }                                                                                                    
3939                                                                                                          
3940     /**                                                                                                  
3941      * Add the views for a widget to the workspace.                                                      
3942      *                                                                                                   
3943      * Implementation of the method from LauncherModel.Callbacks.                                        
3944      */                                                                                                  
3945     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
3946         Runnable r = new Runnable() {                                                                    
3947             public void run() {                                                                          
3948                 bindAppWidget(item);                                                                     
3949             }                                                                                            
3950         };                                                                                               
3951         if (waitUntilResume(r)) {                                                                        
3952             return;                                                                                      
3953         }                                                                                                
3954                                                                                                          
3955         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
3956         if (DEBUG_WIDGETS) {                                                                             
3957             Log.d(TAG, "bindAppWidget: " + item);                                                        
3958         }                                                                                                
3959         final Workspace workspace = mWorkspace;                                                          
3960                                                                                                          
3961         LauncherAppWidgetProviderInfo appWidgetInfo =                                                    
3962                 LauncherModel.getProviderInfo(this, item.providerName, item.user);                       
3963                                                                                                          
3964         if (!mIsSafeModeEnabled                                                                          
3965                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)           
3966                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {              
3967             if (appWidgetInfo == null) {                                                                 
3968                 if (DEBUG_WIDGETS) {                                                                     
3969                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3970                             + " belongs to component " + item.providerName                               
3971                             + ", as the povider is null");                                               
3972                 }                                                                                        
3973                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3974                 return;                                                                                  
3975             }                                                                                            
3976             // Note: This assumes that the id remap broadcast is received before this step.              
3977             // If that is not the case, the id remap will be ignored and user may see the                
3978             // click to setup view.                                                                      
3979             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);            
3980             pendingInfo.spanX = item.spanX;                                                              
3981             pendingInfo.spanY = item.spanY;                                                              
3982             pendingInfo.minSpanX = item.minSpanX;                                                        
3983             pendingInfo.minSpanY = item.minSpanY;                                                        
3984             Bundle options = null;                                                                       
3985             //        AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);              
3986                                                                                                          
3987             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
3988             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
3989                     newWidgetId, appWidgetInfo, options);                                                
3990                                                                                                          
3991             // TODO consider showing a permission dialog when the widget is clicked.                     
3992             if (!success) {                                                                              
3993                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
3994                 if (DEBUG_WIDGETS) {                                                                     
3995                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3996                             + " belongs to component " + item.providerName                               
3997                             + ", as the launcher is unable to bing a new widget id");                    
3998                 }                                                                                        
3999                 LauncherModel.deleteItemFromDatabase(this, item);                                        
4000                 return;                                                                                  
4001             }                                                                                            
4002                                                                                                          
4003             item.appWidgetId = newWidgetId;                                                              
4004                                                                                                          
4005             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4006             // the widget is ready to go.                                                                
4007             item.restoreStatus = (appWidgetInfo.configure == null)                                       
4008                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
4009                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
4010                                                                                                          
4011             LauncherModel.updateItemInDatabase(this, item);                                              
4012         }                                                                                                
4013                                                                                                          
4014         if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {      
4015             final int appWidgetId = item.appWidgetId;                                                    
4016             if (DEBUG_WIDGETS) {                                                                         
4017                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "            
4018                         + appWidgetInfo.provider);                                                       
4019             }                                                                                            
4020                                                                                                          
4021             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4022         } else {                                                                                         
4023             appWidgetInfo = null;                                                                        
4024             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                     
4025                     mIsSafeModeEnabled);                                                                 
4026             view.updateIcon(mIconCache);                                                                 
4027             item.hostView = view;                                                                        
4028             item.hostView.updateAppWidget(null);                                                         
4029             item.hostView.setOnClickListener(this);                                                      
4030         }                                                                                                
4031                                                                                                          
4032         item.hostView.setTag(item);                                                                      
4033         item.onBindAppWidget(this);                                                                      
4034                                                                                                          
4035         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4036                 item.cellY, item.spanX, item.spanY, false);                                              
4037         if (!item.isCustomWidget()) {                                                                    
4038             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
4039         }                                                                                                
4040                                                                                                          
4041         workspace.requestLayout();                                                                       
4042                                                                                                          
4043         if (DEBUG_WIDGETS) {                                                                             
4044             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4045                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4046         }                                                                                                
4047     }                                                                                                    
4048                                                                                                          
4049     /**                                                                                                  
4050      * Restores a pending widget.                                                                        
4051      *                                                                                                   
4052      * @param appWidgetId The app widget id                                                              
4053      * @param cellInfo The position on screen where to create the widget.                                
4054      */                                                                                                  
4055     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4056         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4057         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
4058             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4059             return;                                                                                      
4060         }                                                                                                
4061                                                                                                          
4062         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
4063         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4064                                                                                                          
4065         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4066         LauncherModel.updateItemInDatabase(this, info);                                                  
4067     }                                                                                                    
4068                                                                                                          
4069     public void onPageBoundSynchronously(int page) {                                                     
4070         mSynchronouslyBoundPages.add(page);                                                              
4071     }                                                                                                    
4072                                                                                                          
4073     /**                                                                                                  
4074      * Callback saying that there aren't any more items to bind.                                         
4075      *                                                                                                   
4076      * Implementation of the method from LauncherModel.Callbacks.                                        
4077      */                                                                                                  
4078     public void finishBindingItems() {                                                                   
4079         Runnable r = new Runnable() {                                                                    
4080             public void run() {                                                                          
4081                 finishBindingItems();                                                                    
4082             }                                                                                            
4083         };                                                                                               
4084         if (waitUntilResume(r)) {                                                                        
4085             return;                                                                                      
4086         }                                                                                                
4087         if (mSavedState != null) {                                                                       
4088             if (!mWorkspace.hasFocus()) {                                                                
4089                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4090             }                                                                                            
4091             mSavedState = null;                                                                          
4092         }                                                                                                
4093                                                                                                          
4094         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4095                                                                                                          
4096         setWorkspaceLoading(false);                                                                      
4097         sendLoadingCompleteBroadcastIfNecessary();                                                       
4098                                                                                                          
4099         // If we received the result of any pending adds while the loader was running (e.g. the          
4100         // widget configuration forced an orientation change), process them now.                         
4101         if (sPendingAddItem != null) {                                                                   
4102             final long screenId = completeAdd(sPendingAddItem);                                          
4103                                                                                                          
4104             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4105             // the screen would be guaranteed to exist after bind, and the page would be set through     
4106             // the workspace restore process.                                                            
4107             mWorkspace.post(new Runnable() {                                                             
4108                 @Override                                                                                
4109                 public void run() {                                                                      
4110                     mWorkspace.snapToScreenId(screenId);                                                 
4111                 }                                                                                        
4112             });                                                                                          
4113             sPendingAddItem = null;                                                                      
4114         }                                                                                                
4115                                                                                                          
4116         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4117                                                                                                          
4118         if (mLauncherCallbacks != null) {                                                                
4119             mLauncherCallbacks.finishBindingItems(false);                                                
4120         }                                                                                                
4121     }                                                                                                    
4122                                                                                                          
4123     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4124         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4125             String permission =                                                                          
4126                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4127             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4128             sendBroadcast(intent, permission);                                                           
4129             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4130             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4131             editor.apply();                                                                              
4132         }                                                                                                
4133     }                                                                                                    
4134                                                                                                          
4135     public boolean isAllAppsButtonRank(int rank) {                                                       
4136         if (mHotseat != null) {                                                                          
4137             return mHotseat.isAllAppsButtonRank(rank);                                                   
4138         }                                                                                                
4139         return false;                                                                                    
4140     }                                                                                                    
4141                                                                                                          
4142     private boolean canRunNewAppsAnimation() {                                                           
4143         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4144         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4145     }                                                                                                    
4146                                                                                                          
4147     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4148         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4149                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4150                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4151                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4152         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4153         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4154         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4155         return bounceAnim;                                                                               
4156     }                                                                                                    
4157                                                                                                          
4158     public boolean useVerticalBarLayout() {                                                              
4159         return LauncherAppState.getInstance().getDynamicGrid().                                          
4160                 getDeviceProfile().isVerticalBarLayout();                                                
4161     }                                                                                                    
4162                                                                                                          
4163     protected Rect getSearchBarBounds() {                                                                
4164         return LauncherAppState.getInstance().getDynamicGrid().                                          
4165                 getDeviceProfile().getSearchBarBounds();                                                 
4166     }                                                                                                    
4167                                                                                                          
4168     public void bindSearchablesChanged() {                                                               
4169         if (mSearchDropTargetBar == null) {                                                              
4170             return;                                                                                      
4171         }                                                                                                
4172         if (mQsb != null) {                                                                              
4173             mSearchDropTargetBar.removeView(mQsb);                                                       
4174             mQsb = null;                                                                                 
4175         }                                                                                                
4176         mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                       
4177     }                                                                                                    
4178                                                                                                          
4179     /**                                                                                                  
4180      * Add the icons for all apps.                                                                       
4181      *                                                                                                   
4182      * Implementation of the method from LauncherModel.Callbacks.                                        
4183      */                                                                                                  
4184     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4185         if (mAppsView != null) {                                                                         
4186             mAppsView.setApps(apps);                                                                     
4187         }                                                                                                
4188         if (mWidgetsView != null) {                                                                      
4189             mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),             
4190                     getPackageManager());                                                                
4191         }                                                                                                
4192         if (mLauncherCallbacks != null) {                                                                
4193             mLauncherCallbacks.bindAllApplications(apps);                                                
4194         }                                                                                                
4195     }                                                                                                    
4196                                                                                                          
4197     /**                                                                                                  
4198      * A package was updated.                                                                            
4199      *                                                                                                   
4200      * Implementation of the method from LauncherModel.Callbacks.                                        
4201      */                                                                                                  
4202     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4203         Runnable r = new Runnable() {                                                                    
4204             public void run() {                                                                          
4205                 bindAppsUpdated(apps);                                                                   
4206             }                                                                                            
4207         };                                                                                               
4208         if (waitUntilResume(r)) {                                                                        
4209             return;                                                                                      
4210         }                                                                                                
4211                                                                                                          
4212         if (mAppsView != null) {                                                                         
4213             mAppsView.updateApps(apps);                                                                  
4214         }                                                                                                
4215     }                                                                                                    
4216                                                                                                          
4217     @Override                                                                                            
4218     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                    
4219         Runnable r = new Runnable() {                                                                    
4220             public void run() {                                                                          
4221                 bindWidgetsRestored(widgets);                                                            
4222             }                                                                                            
4223         };                                                                                               
4224         if (waitUntilResume(r)) {                                                                        
4225             return;                                                                                      
4226         }                                                                                                
4227         mWorkspace.widgetsRestored(widgets);                                                             
4228     }                                                                                                    
4229                                                                                                          
4230     /**                                                                                                  
4231      * Some shortcuts were updated in the background.                                                    
4232      *                                                                                                   
4233      * Implementation of the method from LauncherModel.Callbacks.                                        
4234      */                                                                                                  
4235     @Override                                                                                            
4236     public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                              
4237             final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                        
4238         Runnable r = new Runnable() {                                                                    
4239             public void run() {                                                                          
4240                 bindShortcutsChanged(updated, removed, user);                                            
4241             }                                                                                            
4242         };                                                                                               
4243         if (waitUntilResume(r)) {                                                                        
4244             return;                                                                                      
4245         }                                                                                                
4246                                                                                                          
4247         if (!updated.isEmpty()) {                                                                        
4248             mWorkspace.updateShortcuts(updated);                                                         
4249         }                                                                                                
4250                                                                                                          
4251         if (!removed.isEmpty()) {                                                                        
4252             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4253             for (ShortcutInfo si : removed) {                                                            
4254                 removedComponents.add(si.getTargetComponent());                                          
4255             }                                                                                            
4256             mWorkspace.removeItemsByComponentName(removedComponents, user);                              
4257             // Notify the drag controller                                                                
4258             mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                   
4259         }                                                                                                
4260     }                                                                                                    
4261                                                                                                          
4262     /**                                                                                                  
4263      * Update the state of a package, typically related to install state.                                
4264      *                                                                                                   
4265      * Implementation of the method from LauncherModel.Callbacks.                                        
4266      */                                                                                                  
4267     @Override                                                                                            
4268     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4269         if (mWorkspace != null) {                                                                        
4270             mWorkspace.updatePackageState(installInfo);                                                  
4271         }                                                                                                
4272     }                                                                                                    
4273                                                                                                          
4274     /**                                                                                                  
4275      * Update the label and icon of all the icons in a package                                           
4276      *                                                                                                   
4277      * Implementation of the method from LauncherModel.Callbacks.                                        
4278      */                                                                                                  
4279     @Override                                                                                            
4280     public void updatePackageBadge(String packageName) {                                                 
4281         if (mWorkspace != null) {                                                                        
4282             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4283         }                                                                                                
4284     }                                                                                                    
4285                                                                                                          
4286     /**                                                                                                  
4287      * A package was uninstalled.  We take both the super set of packageNames                            
4288      * in addition to specific applications to remove, the reason being that                             
4289      * this can be called when a package is updated as well.  In that scenario,                          
4290      * we only remove specific components from the workspace, where as                                   
4291      * package-removal should clear all items by package name.                                           
4292      *                                                                                                   
4293      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4294      * Implementation of the method from LauncherModel.Callbacks.                                        
4295      */                                                                                                  
4296     @Override                                                                                            
4297     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
4298             final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {          
4299         Runnable r = new Runnable() {                                                                    
4300             public void run() {                                                                          
4301                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4302             }                                                                                            
4303         };                                                                                               
4304         if (waitUntilResume(r)) {                                                                        
4305             return;                                                                                      
4306         }                                                                                                
4307                                                                                                          
4308         if (reason == 0) {                                                                               
4309             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4310             for (AppInfo info : appInfos) {                                                              
4311                 removedComponents.add(info.componentName);                                               
4312             }                                                                                            
4313             if (!packageNames.isEmpty()) {                                                               
4314                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4315             }                                                                                            
4316             if (!removedComponents.isEmpty()) {                                                          
4317                 mWorkspace.removeItemsByComponentName(removedComponents, user);                          
4318             }                                                                                            
4319             // Notify the drag controller                                                                
4320             mDragController.onAppsRemoved(packageNames, removedComponents);                              
4321                                                                                                          
4322         } else {                                                                                         
4323             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4324         }                                                                                                
4325                                                                                                          
4326         // Update AllApps                                                                                
4327         if (mAppsView != null) {                                                                         
4328             mAppsView.removeApps(appInfos);                                                              
4329         }                                                                                                
4330     }                                                                                                    
4331                                                                                                          
4332     /**                                                                                                  
4333      * A number of packages were updated.                                                                
4334      */                                                                                                  
4335     @Thunk ArrayList<Object> mWidgetsAndShortcuts;                                                       
4336     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4337             public void run() {                                                                          
4338                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4339                 mWidgetsAndShortcuts = null;                                                             
4340             }                                                                                            
4341         };                                                                                               
4342                                                                                                          
4343     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4344         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4345             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4346             return;                                                                                      
4347         }                                                                                                
4348                                                                                                          
4349         if (mWidgetsView != null) {                                                                      
4350             mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),             
4351                     getPackageManager());                                                                
4352         }                                                                                                
4353     }                                                                                                    
4354                                                                                                          
4355     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4356         final Display d = getWindowManager().getDefaultDisplay();                                        
4357         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4358         switch (d.getRotation()) {                                                                       
4359         case Surface.ROTATION_0:                                                                         
4360         case Surface.ROTATION_180:                                                                       
4361             // We are currently in the same basic orientation as the natural orientation                 
4362             naturalOri = configOri;                                                                      
4363             break;                                                                                       
4364         case Surface.ROTATION_90:                                                                        
4365         case Surface.ROTATION_270:                                                                       
4366             // We are currently in the other basic orientation to the natural orientation                
4367             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4368                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4369             break;                                                                                       
4370         }                                                                                                
4371                                                                                                          
4372         int[] oriMap = {                                                                                 
4373                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4374                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4375                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4376                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4377         };                                                                                               
4378         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4379         // is landscape.                                                                                 
4380         int indexOffset = 0;                                                                             
4381         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4382             indexOffset = 1;                                                                             
4383         }                                                                                                
4384         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4385     }                                                                                                    
4386                                                                                                          
4387     public void lockScreenOrientation() {                                                                
4388         if (Utilities.isRotationEnabled(this)) {                                                         
4389             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                            
4390                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                
4391                         .getConfiguration().orientation));                                               
4392             } else {                                                                                     
4393                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                         
4394             }                                                                                            
4395         }                                                                                                
4396     }                                                                                                    
4397     public void unlockScreenOrientation(boolean immediate) {                                             
4398         if (Utilities.isRotationEnabled(this)) {                                                         
4399             if (immediate) {                                                                             
4400                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4401             } else {                                                                                     
4402                 mHandler.postDelayed(new Runnable() {                                                    
4403                     public void run() {                                                                  
4404                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4405                     }                                                                                    
4406                 }, mRestoreScreenOrientationDelay);                                                      
4407             }                                                                                            
4408         }                                                                                                
4409     }                                                                                                    
4410                                                                                                          
4411     protected boolean isLauncherPreinstalled() {                                                         
4412         if (mLauncherCallbacks != null) {                                                                
4413             return mLauncherCallbacks.isLauncherPreinstalled();                                          
4414         }                                                                                                
4415         PackageManager pm = getPackageManager();                                                         
4416         try {                                                                                            
4417             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4418             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4419                 return true;                                                                             
4420             } else {                                                                                     
4421                 return false;                                                                            
4422             }                                                                                            
4423         } catch (NameNotFoundException e) {                                                              
4424             e.printStackTrace();                                                                         
4425             return false;                                                                                
4426         }                                                                                                
4427     }                                                                                                    
4428                                                                                                          
4429     /**                                                                                                  
4430      * This method indicates whether or not we should suggest default wallpaper dimensions               
4431      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4432      */                                                                                                  
4433     protected boolean overrideWallpaperDimensions() {                                                    
4434         if (mLauncherCallbacks != null) {                                                                
4435             return mLauncherCallbacks.overrideWallpaperDimensions();                                     
4436         }                                                                                                
4437         return true;                                                                                     
4438     }                                                                                                    
4439                                                                                                          
4440     /**                                                                                                  
4441      * To be overridden by subclasses to indicate that there is an activity to launch                    
4442      * before showing the standard launcher experience.                                                  
4443      */                                                                                                  
4444     protected boolean hasFirstRunActivity() {                                                            
4445         if (mLauncherCallbacks != null) {                                                                
4446             return mLauncherCallbacks.hasFirstRunActivity();                                             
4447         }                                                                                                
4448         return false;                                                                                    
4449     }                                                                                                    
4450                                                                                                          
4451     /**                                                                                                  
4452      * To be overridden by subclasses to launch any first run activity                                   
4453      */                                                                                                  
4454     protected Intent getFirstRunActivity() {                                                             
4455         if (mLauncherCallbacks != null) {                                                                
4456             return mLauncherCallbacks.getFirstRunActivity();                                             
4457         }                                                                                                
4458         return null;                                                                                     
4459     }                                                                                                    
4460                                                                                                          
4461     /**                                                                                                  
4462      * Returns whether the launcher callbacks overrides search in all apps.                              
4463      * @return                                                                                           
4464      */                                                                                                  
4465     @Thunk boolean isAllAppsSearchOverridden() {                                                         
4466         if (mLauncherCallbacks != null) {                                                                
4467             return mLauncherCallbacks.overrideAllAppsSearch();                                           
4468         }                                                                                                
4469         return false;                                                                                    
4470     }                                                                                                    
4471                                                                                                          
4472     private boolean shouldRunFirstRunActivity() {                                                        
4473         return !ActivityManager.isRunningInTestHarness() &&                                              
4474                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4475     }                                                                                                    
4476                                                                                                          
4477     protected boolean hasRunFirstRunActivity() {                                                         
4478         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4479     }                                                                                                    
4480                                                                                                          
4481     public boolean showFirstRunActivity() {                                                              
4482         if (shouldRunFirstRunActivity() &&                                                               
4483                 hasFirstRunActivity()) {                                                                 
4484             Intent firstRunIntent = getFirstRunActivity();                                               
4485             if (firstRunIntent != null) {                                                                
4486                 startActivity(firstRunIntent);                                                           
4487                 markFirstRunActivityShown();                                                             
4488                 return true;                                                                             
4489             }                                                                                            
4490         }                                                                                                
4491         return false;                                                                                    
4492     }                                                                                                    
4493                                                                                                          
4494     private void markFirstRunActivityShown() {                                                           
4495         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4496         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4497         editor.apply();                                                                                  
4498     }                                                                                                    
4499                                                                                                          
4500     /**                                                                                                  
4501      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4502      * screen that must be displayed and dismissed.                                                      
4503      */                                                                                                  
4504     protected boolean hasDismissableIntroScreen() {                                                      
4505         if (mLauncherCallbacks != null) {                                                                
4506             return mLauncherCallbacks.hasDismissableIntroScreen();                                       
4507         }                                                                                                
4508         return false;                                                                                    
4509     }                                                                                                    
4510                                                                                                          
4511     /**                                                                                                  
4512      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4513      */                                                                                                  
4514     protected View getIntroScreen() {                                                                    
4515         if (mLauncherCallbacks != null) {                                                                
4516             return mLauncherCallbacks.getIntroScreen();                                                  
4517         }                                                                                                
4518         return null;                                                                                     
4519     }                                                                                                    
4520                                                                                                          
4521     /**                                                                                                  
4522      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4523      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4524      */                                                                                                  
4525     private boolean shouldShowIntroScreen() {                                                            
4526         return hasDismissableIntroScreen() &&                                                            
4527                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4528     }                                                                                                    
4529                                                                                                          
4530     protected void showIntroScreen() {                                                                   
4531         View introScreen = getIntroScreen();                                                             
4532         changeWallpaperVisiblity(false);                                                                 
4533         if (introScreen != null) {                                                                       
4534             mDragLayer.showOverlayView(introScreen);                                                     
4535         }                                                                                                
4536         if (mLauncherOverlayContainer != null) {                                                         
4537             mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                     
4538         }                                                                                                
4539     }                                                                                                    
4540                                                                                                          
4541     public void dismissIntroScreen() {                                                                   
4542         markIntroScreenDismissed();                                                                      
4543         if (showFirstRunActivity()) {                                                                    
4544             // We delay hiding the intro view until the first run activity is showing. This              
4545             // avoids a blip.                                                                            
4546             mWorkspace.postDelayed(new Runnable() {                                                      
4547                 @Override                                                                                
4548                 public void run() {                                                                      
4549                     mDragLayer.dismissOverlayView();                                                     
4550                     if (mLauncherOverlayContainer != null) {                                             
4551                         mLauncherOverlayContainer.setVisibility(View.VISIBLE);                           
4552                     }                                                                                    
4553                     showFirstRunClings();                                                                
4554                 }                                                                                        
4555             }, ACTIVITY_START_DELAY);                                                                    
4556         } else {                                                                                         
4557             mDragLayer.dismissOverlayView();                                                             
4558             if (mLauncherOverlayContainer != null) {                                                     
4559                 mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                   
4560             }                                                                                            
4561             showFirstRunClings();                                                                        
4562         }                                                                                                
4563         changeWallpaperVisiblity(true);                                                                  
4564     }                                                                                                    
4565                                                                                                          
4566     private void markIntroScreenDismissed() {                                                            
4567         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4568         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
4569         editor.apply();                                                                                  
4570     }                                                                                                    
4571                                                                                                          
4572     @Thunk void showFirstRunClings() {                                                                   
4573         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
4574         // on the device, then we always show the first run cling experience (or if there is no          
4575         // launcher2). Otherwise, we prompt the user upon started for migration                          
4576         LauncherClings launcherClings = new LauncherClings(this);                                        
4577         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
4578             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
4579                 launcherClings.showMigrationCling();                                                     
4580             } else {                                                                                     
4581                 launcherClings.showLongPressCling(true);                                                 
4582             }                                                                                            
4583         }                                                                                                
4584     }                                                                                                    
4585                                                                                                          
4586     void showWorkspaceSearchAndHotseat() {                                                               
4587         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
4588         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
4589         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
4590         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
4591     }                                                                                                    
4592                                                                                                          
4593     void hideWorkspaceSearchAndHotseat() {                                                               
4594         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
4595         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
4596         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
4597         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
4598     }                                                                                                    
4599                                                                                                          
4600     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
4601         // Called from search suggestion, not supported in other profiles.                               
4602         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
4603         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
4604         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
4605                 myUser);                                                                                 
4606         if (activityInfo == null) {                                                                      
4607             return null;                                                                                 
4608         }                                                                                                
4609         return new AppInfo(this, activityInfo, myUser, mIconCache);                                      
4610     }                                                                                                    
4611                                                                                                          
4612     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4613             Bitmap icon) {                                                                               
4614         // Called from search suggestion, not supported in other profiles.                               
4615         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
4616                 UserHandleCompat.myUserHandle());                                                        
4617     }                                                                                                    
4618                                                                                                          
4619     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4620             Bitmap icon, UserHandleCompat user) {                                                        
4621         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
4622         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
4623         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
4624     }                                                                                                    
4625                                                                                                          
4626     protected void moveWorkspaceToDefaultScreen() {                                                      
4627         mWorkspace.moveToDefaultScreen(false);                                                           
4628     }                                                                                                    
4629                                                                                                          
4630     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
4631         dragView.setTag(dragInfo);                                                                       
4632         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
4633         mWorkspace.beginExternalDragShared(dragView, source);                                            
4634     }                                                                                                    
4635                                                                                                          
4636     @Override                                                                                            
4637     public void onPageSwitch(View newPage, int newPageIndex) {                                           
4638         if (mLauncherCallbacks != null) {                                                                
4639             mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                      
4640         }                                                                                                
4641     }                                                                                                    
4642                                                                                                          
4643     /**                                                                                                  
4644      * Prints out out state for debugging.                                                               
4645      */                                                                                                  
4646     public void dumpState() {                                                                            
4647         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
4648         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
4649         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
4650         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
4651         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
4652         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
4653         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
4654         mModel.dumpState();                                                                              
4655         // TODO(hyunyoungs): add mWidgetsView.dumpState(); or mWidgetsModel.dumpState();                 
4656                                                                                                          
4657         Log.d(TAG, "END launcher3 dump state");                                                          
4658     }                                                                                                    
4659                                                                                                          
4660     @Override                                                                                            
4661     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
4662         super.dump(prefix, fd, writer, args);                                                            
4663         synchronized (sDumpLogs) {                                                                       
4664             writer.println(" ");                                                                         
4665             writer.println("Debug logs: ");                                                              
4666             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
4667                 writer.println("  " + sDumpLogs.get(i));                                                 
4668             }                                                                                            
4669         }                                                                                                
4670         if (mLauncherCallbacks != null) {                                                                
4671             mLauncherCallbacks.dump(prefix, fd, writer, args);                                           
4672         }                                                                                                
4673     }                                                                                                    
4674                                                                                                          
4675     public static void dumpDebugLogsToConsole() {                                                        
4676         if (DEBUG_DUMP_LOG) {                                                                            
4677             synchronized (sDumpLogs) {                                                                   
4678                 Log.d(TAG, "");                                                                          
4679                 Log.d(TAG, "*********************");                                                     
4680                 Log.d(TAG, "Launcher debug logs: ");                                                     
4681                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
4682                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
4683                 }                                                                                        
4684                 Log.d(TAG, "*********************");                                                     
4685                 Log.d(TAG, "");                                                                          
4686             }                                                                                            
4687         }                                                                                                
4688     }                                                                                                    
4689                                                                                                          
4690     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
4691         addDumpLog(tag, log, null, debugLog);                                                            
4692     }                                                                                                    
4693                                                                                                          
4694     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
4695         if (debugLog) {                                                                                  
4696             if (e != null) {                                                                             
4697                 Log.d(tag, log, e);                                                                      
4698             } else {                                                                                     
4699                 Log.d(tag, log);                                                                         
4700             }                                                                                            
4701         }                                                                                                
4702         if (DEBUG_DUMP_LOG) {                                                                            
4703             sDateStamp.setTime(System.currentTimeMillis());                                              
4704             synchronized (sDumpLogs) {                                                                   
4705                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
4706                     + (e == null ? "" : (", Exception: " + e)));                                         
4707             }                                                                                            
4708         }                                                                                                
4709     }                                                                                                    
4710                                                                                                          
4711     public static CustomAppWidget getCustomAppWidget(String name) {                                      
4712         return sCustomAppWidgets.get(name);                                                              
4713     }                                                                                                    
4714                                                                                                          
4715     public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                               
4716         return sCustomAppWidgets;                                                                        
4717     }                                                                                                    
4718                                                                                                          
4719     public void dumpLogsToLocalData() {                                                                  
4720         if (DEBUG_DUMP_LOG) {                                                                            
4721             new AsyncTask<Void, Void, Void>() {                                                          
4722                 public Void doInBackground(Void ... args) {                                              
4723                     boolean success = false;                                                             
4724                     sDateStamp.setTime(sRunStart);                                                       
4725                     String FILENAME = sDateStamp.getMonth() + "-"                                        
4726                             + sDateStamp.getDay() + "_"                                                  
4727                             + sDateStamp.getHours() + "-"                                                
4728                             + sDateStamp.getMinutes() + "_"                                              
4729                             + sDateStamp.getSeconds() + ".txt";                                          
4730                                                                                                          
4731                     FileOutputStream fos = null;                                                         
4732                     File outFile = null;                                                                 
4733                     try {                                                                                
4734                         outFile = new File(getFilesDir(), FILENAME);                                     
4735                         outFile.createNewFile();                                                         
4736                         fos = new FileOutputStream(outFile);                                             
4737                     } catch (Exception e) {                                                              
4738                         e.printStackTrace();                                                             
4739                     }                                                                                    
4740                     if (fos != null) {                                                                   
4741                         PrintWriter writer = new PrintWriter(fos);                                       
4742                                                                                                          
4743                         writer.println(" ");                                                             
4744                         writer.println("Debug logs: ");                                                  
4745                         synchronized (sDumpLogs) {                                                       
4746                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
4747                                 writer.println("  " + sDumpLogs.get(i));                                 
4748                             }                                                                            
4749                         }                                                                                
4750                         writer.close();                                                                  
4751                     }                                                                                    
4752                     try {                                                                                
4753                         if (fos != null) {                                                               
4754                             fos.close();                                                                 
4755                             success = true;                                                              
4756                         }                                                                                
4757                     } catch (IOException e) {                                                            
4758                         e.printStackTrace();                                                             
4759                     }                                                                                    
4760                     return null;                                                                         
4761                 }                                                                                        
4762             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
4763         }                                                                                                
4764     }                                                                                                    
4765 }                                                                                                        
4766                                                                                                          
4767 interface LauncherTransitionable {                                                                       
4768     View getContent();                                                                                   
4769     void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                 
4770     void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                   
4771     void onLauncherTransitionStep(Launcher l, float t);                                                  
4772     void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                     
4773 }                                                                                                        
4774                                                                                                          
4775 interface DebugIntents {                                                                                 
4776     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
4777     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
4778 }                                                                                                        
   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16                                                                                                          
  17 package com.android.launcher3;                                                                           
  18                                                                                                          
  19 import android.animation.Animator;                                                                       
  20 import android.animation.AnimatorListenerAdapter;                                                        
  21 import android.animation.AnimatorSet;                                                                    
  22 import android.animation.ObjectAnimator;                                                                 
  23 import android.animation.PropertyValuesHolder;                                                           
  24 import android.animation.ValueAnimator;                                                                  
  25 import android.annotation.TargetApi;                                                                     
  26 import android.app.Activity;                                                                             
  27 import android.app.ActivityManager;                                                                      
  28 import android.app.ActivityOptions;                                                                      
  29 import android.app.AlertDialog;                                                                          
  30 import android.app.SearchManager;                                                                        
  31 import android.appwidget.AppWidgetHostView;                                                              
  32 import android.appwidget.AppWidgetManager;                                                               
  33 import android.appwidget.AppWidgetProviderInfo;                                                          
  34 import android.content.ActivityNotFoundException;                                                        
  35 import android.content.BroadcastReceiver;                                                                
  36 import android.content.ComponentCallbacks2;                                                              
  37 import android.content.ComponentName;                                                                    
  38 import android.content.ContentResolver;                                                                  
  39 import android.content.Context;                                                                          
  40 import android.content.DialogInterface;                                                                  
  41 import android.content.Intent;                                                                           
  42 import android.content.IntentFilter;                                                                     
  43 import android.content.IntentSender;                                                                     
  44 import android.content.SharedPreferences;                                                                
  45 import android.content.pm.ActivityInfo;                                                                  
  46 import android.content.pm.ApplicationInfo;                                                               
  47 import android.content.pm.PackageManager;                                                                
  48 import android.content.pm.PackageManager.NameNotFoundException;                                          
  49 import android.content.res.Configuration;                                                                
  50 import android.database.ContentObserver;                                                                 
  51 import android.database.sqlite.SQLiteDatabase;                                                           
  52 import android.graphics.Bitmap;                                                                          
  53 import android.graphics.Canvas;                                                                          
  54 import android.graphics.Color;                                                                           
  55 import android.graphics.PorterDuff;                                                                      
  56 import android.graphics.Rect;                                                                            
  57 import android.graphics.drawable.Drawable;                                                               
  58 import android.net.Uri;                                                                                  
  59 import android.os.AsyncTask;                                                                             
  60 import android.os.Build;                                                                                 
  61 import android.os.Bundle;                                                                                
  62 import android.os.Environment;                                                                           
  63 import android.os.Handler;                                                                               
  64 import android.os.Message;                                                                               
  65 import android.os.StrictMode;                                                                            
  66 import android.os.SystemClock;                                                                           
  67 import android.text.Selection;                                                                           
  68 import android.text.SpannableStringBuilder;                                                              
  69 import android.text.TextUtils;                                                                           
  70 import android.text.method.TextKeyListener;                                                              
  71 import android.util.Log;                                                                                 
  72 import android.view.Display;                                                                             
  73 import android.view.Gravity;                                                                             
  74 import android.view.HapticFeedbackConstants;                                                             
  75 import android.view.KeyEvent;                                                                            
  76 import android.view.LayoutInflater;                                                                      
  77 import android.view.Menu;                                                                                
  78 import android.view.MotionEvent;                                                                         
  79 import android.view.Surface;                                                                             
  80 import android.view.View;                                                                                
  81 import android.view.View.OnClickListener;                                                                
  82 import android.view.View.OnLongClickListener;                                                            
  83 import android.view.ViewGroup;                                                                           
  84 import android.view.ViewStub;                                                                            
  85 import android.view.ViewTreeObserver;                                                                    
  86 import android.view.Window;                                                                              
  87 import android.view.WindowManager;                                                                       
  88 import android.view.accessibility.AccessibilityEvent;                                                    
  89 import android.view.inputmethod.InputMethodManager;                                                      
  90 import android.widget.Advanceable;                                                                       
  91 import android.widget.FrameLayout;                                                                       
  92 import android.widget.ImageView;                                                                         
  93 import android.widget.TextView;                                                                          
  94 import android.widget.Toast;                                                                             
  95                                                                                                          
  96 import com.android.launcher3.DropTarget.DragObject;                                                      
  97 import com.android.launcher3.PagedView.PageSwitchListener;                                               
  98 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
  99 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
 100 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
 101 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 102 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 103 import com.android.launcher3.compat.UserHandleCompat;                                                    
 104 import com.android.launcher3.compat.UserManagerCompat;                                                   
 105 import com.android.launcher3.util.Thunk;                                                                 
 106 import com.android.launcher3.widget.PendingAddWidgetInfo;                                                
 107 import com.android.launcher3.widget.WidgetsContainerView;                                                
 108                                                                                                          
 109 import java.io.DataInputStream;                                                                          
 110 import java.io.DataOutputStream;                                                                         
 111 import java.io.File;                                                                                     
 112 import java.io.FileDescriptor;                                                                           
 113 import java.io.FileNotFoundException;                                                                    
 114 import java.io.FileOutputStream;                                                                         
 115 import java.io.IOException;                                                                              
 116 import java.io.PrintWriter;                                                                              
 117 import java.lang.reflect.InvocationTargetException;                                                      
 118 import java.lang.reflect.Method;                                                                         
 119 import java.text.DateFormat;                                                                             
 120 import java.util.ArrayList;                                                                              
 121 import java.util.Collection;                                                                             
 122 import java.util.Date;                                                                                   
 123 import java.util.HashMap;                                                                                
 124 import java.util.HashSet;                                                                                
 125 import java.util.List;                                                                                   
 126 import java.util.concurrent.atomic.AtomicInteger;                                                        
 127                                                                                                          
 128 /**                                                                                                      
 129  * Default launcher application.                                                                         
 130  */                                                                                                      
 131 public class Launcher extends Activity                                                                   
 132         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                   
 133                    View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,             
 134                    LauncherStateTransitionAnimation.Callbacks {                                          
 135     static final String TAG = "Launcher";                                                                
 136     static final boolean LOGD = true;                                                                    
 137                                                                                                          
 138     static final boolean PROFILE_STARTUP = false;                                                        
 139     static final boolean DEBUG_WIDGETS = true;                                                           
 140     static final boolean DEBUG_STRICT_MODE = false;                                                      
 141     static final boolean DEBUG_RESUME_TIME = false;                                                      
 142     static final boolean DEBUG_DUMP_LOG = false;                                                         
 143                                                                                                          
 144     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 145                                                                                                          
 146     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 147     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 148     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 149     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 150                                                                                                          
 151     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 152     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 153                                                                                                          
 154     /**                                                                                                  
 155      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 156      * request codes used internally.                                                                    
 157      */                                                                                                  
 158     protected static final int REQUEST_LAST = 100;                                                       
 159                                                                                                          
 160     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 161                                                                                                          
 162     static final int SCREEN_COUNT = 5;                                                                   
 163                                                                                                          
 164     // To turn on these properties, type                                                                 
 165     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 166     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 167                                                                                                          
 168     // The Intent extra that defines whether to ignore the launch animation                              
 169     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 170             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 171                                                                                                          
 172     // Type: int                                                                                         
 173     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 174     // Type: int                                                                                         
 175     private static final String RUNTIME_STATE = "launcher.state";                                        
 176     // Type: int                                                                                         
 177     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 178     // Type: int                                                                                         
 179     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 180     // Type: int                                                                                         
 181     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 182     // Type: int                                                                                         
 183     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 184     // Type: boolean                                                                                     
 185     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 186     // Type: long                                                                                        
 187     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 188     // Type: int                                                                                         
 189     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 190     // Type: int                                                                                         
 191     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 192     // Type: parcelable                                                                                  
 193     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 194     // Type: parcelable                                                                                  
 195     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 196     // Type: int[]                                                                                       
 197     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 198                                                                                                          
 199     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 200     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 201                                                                                                          
 202     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 203     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 204             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 205                                                                                                          
 206     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 207     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 208                                                                                                          
 209     private static final String QSB_WIDGET_ID = "qsb_widget_id";                                         
 210     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                             
 211                                                                                                          
 212     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 213                                                                                                          
 214     /** The different states that Launcher can be in. */                                                 
 215                                                                                                          
 216                                                                                                          
 217     /** The different states that Launcher can be in. */                                                 
 218     enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED,, };;         
 219     @Thunk State mState = State.WORKSPACE;                                                               
 220     @Thunk AnimatorSet mStateAnimation;                                                                  
 221     @Thunk LauncherStateTransitionAnimation mStateTransitionAnimation;                                   
 222                                                                                                          
 223     private boolean mIsSafeModeEnabled;                                                                  
 224                                                                                                          
 225     LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();             
 226     LauncherOverlay mLauncherOverlay;                                                                    
 227     InsettableFrameLayout mLauncherOverlayContainer;                                                     
 228                                                                                                          
 229     static final int APPWIDGET_HOST_ID = 1024;                                                           
 230     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 231     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 232     private static final int ACTIVITY_START_DELAY = 1000;                                                
 233                                                                                                          
 234     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 235     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 236                                                                                                          
 237     // How long to wait before the new-shortcut animation automatically pans the workspace               
 238     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 239     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 240     @Thunk static int NEW_APPS_ANIMATION_DELAY = 500;                                                    
 241                                                                                                          
 242     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 243             = new CloseSystemDialogsIntentReceiver();                                                    
 244     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 245                                                                                                          
 246     private LayoutInflater mInflater;                                                                    
 247                                                                                                          
 248     @Thunk Workspace mWorkspace;                                                                         
 249     private View mLauncherView;                                                                          
 250     private View mPageIndicators;                                                                        
 251     @Thunk DragLayer mDragLayer;                                                                         
 252     private DragController mDragController;                                                              
 253     private View mWeightWatcher;                                                                         
 254                                                                                                          
 255     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 256     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 257                                                                                                          
 258     @Thunk ItemInfo mPendingAddInfo = new ItemInfo();                                                    
 259     private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                         
 260     private int mPendingAddWidgetId = -1;                                                                
 261                                                                                                          
 262     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 263                                                                                                          
 264     private FolderInfo mFolderInfo;                                                                      
 265                                                                                                          
 266     private Hotseat mHotseat;                                                                            
 267     private ViewGroup mOverviewPanel;                                                                    
 268                                                                                                          
 269     private View mAllAppsButton;                                                                         
 270                                                                                                          
 271     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 272                                                                                                          
 273     // Main container view for the all apps screen.                                                      
 274     @Thunk AppsContainerView mAppsView;                                                                  
 275                                                                                                          
 276     // Main container view for the widget tray screen.                                                   
 277     private WidgetsContainerView mWidgetsView;                                                           
 278                                                                                                          
 279     private boolean mAutoAdvanceRunning = false;                                                         
 280     private AppWidgetHostView mQsb;                                                                      
 281                                                                                                          
 282     private Bundle mSavedState;                                                                          
 283     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 284     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 285     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 286     private State mOnResumeState = State.NONE;                                                           
 287                                                                                                          
 288     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 289                                                                                                          
 290     @Thunk boolean mWorkspaceLoading = true;                                                             
 291                                                                                                          
 292     private boolean mPaused = true;                                                                      
 293     private boolean mRestoring;                                                                          
 294     private boolean mWaitingForResult;                                                                   
 295     private boolean mOnResumeNeedsLoad;                                                                  
 296                                                                                                          
 297     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 298     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 299                                                                                                          
 300     private Bundle mSavedInstanceState;                                                                  
 301                                                                                                          
 302     private LauncherModel mModel;                                                                        
 303     private IconCache mIconCache;                                                                        
 304     @Thunk boolean mUserPresent = true;                                                                  
 305     private boolean mVisible = false;                                                                    
 306     private boolean mHasFocus = false;                                                                   
 307     private boolean mAttached = false;                                                                   
 308                                                                                                          
 309     @Thunk static LocaleConfiguration sLocaleConfiguration = null;                                       
 310                                                                                                          
 311     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 312                                                                                                          
 313     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 314                                                                                                          
 315     // Related to the auto-advancing of widgets                                                          
 316     private final int ADVANCE_MSG = 1;                                                                   
 317     private final int mAdvanceInterval = 20000;                                                          
 318     private final int mAdvanceStagger = 250;                                                             
 319     private long mAutoAdvanceSentTime;                                                                   
 320     private long mAutoAdvanceTimeLeft = -1;                                                              
 321     @Thunk HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                      
 322         new HashMap<View, AppWidgetProviderInfo>();                                                      
 323                                                                                                          
 324     // Determines how long to wait after a rotation before restoring the screen orientation to           
 325     // match the sensor state.                                                                           
 326     private final int mRestoreScreenOrientationDelay = 500;                                              
 327                                                                                                          
 328     @Thunk Drawable mWorkspaceBackgroundDrawable;                                                        
 329                                                                                                          
 330     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 331     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 332                                                                                                          
 333     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 334     static Date sDateStamp = new Date();                                                                 
 335     static DateFormat sDateFormat =                                                                      
 336             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                          
 337     static long sRunStart = System.currentTimeMillis();                                                  
 338     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 339                                                                                                          
 340     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 341     // it from the context.                                                                              
 342     private SharedPreferences mSharedPrefs;                                                              
 343                                                                                                          
 344     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 345     // when we scroll to that page on resume.                                                            
 346     @Thunk ImageView mFolderIconImageView;                                                               
 347     private Bitmap mFolderIconBitmap;                                                                    
 348     private Canvas mFolderIconCanvas;                                                                    
 349     private Rect mRectForFolderAnimation = new Rect();                                                   
 350                                                                                                          
 351     private BubbleTextView mWaitingForResume;                                                            
 352                                                                                                          
 353     protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                
 354             new HashMap<String, CustomAppWidget>();                                                      
 355                                                                                                          
 356     private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                      
 357                                                                                                          
 358     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 359     private static Method sClipRevealMethod = null;                                                      
 360     static {                                                                                             
 361         Class<?> activityOptionsClass = ActivityOptions.class;                                           
 362         try {                                                                                            
 363             sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",        
 364                     View.class, int.class, int.class, int.class, int.class);                             
 365         } catch (Exception e) {                                                                          
 366             // Earlier version                                                                           
 367         }                                                                                                
 368     }                                                                                                    
 369     static {                                                                                             
 370         if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                 
 371             sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                       
 372         }                                                                                                
 373     }                                                                                                    
 374                                                                                                          
 375     @Thunk Runnable mBuildLayersRunnable = new Runnable() {                                              
 376         public void run() {                                                                              
 377             if (mWorkspace != null) {                                                                    
 378                 mWorkspace.buildPageHardwareLayers();                                                    
 379             }                                                                                            
 380         }                                                                                                
 381     };                                                                                                   
 382                                                                                                          
 383     private static PendingAddArguments sPendingAddItem;                                                  
 384                                                                                                          
 385     @Thunk static class PendingAddArguments {                                                            
 386         int requestCode;                                                                                 
 387         Intent intent;                                                                                   
 388         long container;                                                                                  
 389         long screenId;                                                                                   
 390         int cellX;                                                                                       
 391         int cellY;                                                                                       
 392         int appWidgetId;                                                                                 
 393     }                                                                                                    
 394                                                                                                          
 395     private Stats mStats;                                                                                
 396                                                                                                          
 397     FocusIndicatorView mFocusHandler;                                                                    
 398                                                                                                          
 399     @Override                                                                                            
 400     protected void onCreate(Bundle savedInstanceState) {                                                 
 401         if (DEBUG_STRICT_MODE) {                                                                         
 402             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                             
 403                     .detectDiskReads()                                                                   
 404                     .detectDiskWrites()                                                                  
 405                     .detectNetwork()   // or .detectAll() for all detectable problems                    
 406                     .penaltyLog()                                                                        
 407                     .build());                                                                           
 408             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                     
 409                     .detectLeakedSqlLiteObjects()                                                        
 410                     .detectLeakedClosableObjects()                                                       
 411                     .penaltyLog()                                                                        
 412                     .penaltyDeath()                                                                      
 413                     .build());                                                                           
 414         }                                                                                                
 415                                                                                                          
 416         if (mLauncherCallbacks != null) {                                                                
 417             mLauncherCallbacks.preOnCreate();                                                            
 418         }                                                                                                
 419                                                                                                          
 420         super.onCreate(savedInstanceState);                                                              
 421                                                                                                          
 422         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 423         LauncherAppState app = LauncherAppState.getInstance();                                           
 424         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 425                                                                                                          
 426         // Lazy-initialize the dynamic grid                                                              
 427         DeviceProfile grid = app.initDynamicGrid(this);                                                  
 428                                                                                                          
 429         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 430         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                  
 431                 Context.MODE_PRIVATE);                                                                   
 432         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 433         mModel = app.setLauncher(this);                                                                  
 434         mIconCache = app.getIconCache();                                                                 
 435         mIconCache.flushInvalidIcons(grid);                                                              
 436         mDragController = new DragController(this);                                                      
 437         mInflater = getLayoutInflater();                                                                 
 438         mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                    
 439                                                                                                          
 440         mStats = new Stats(this);                                                                        
 441                                                                                                          
 442         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 443                                                                                                          
 444         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 445         mAppWidgetHost.startListening();                                                                 
 446                                                                                                          
 447         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 448         // this also ensures that any synchronous binding below doesn't re-trigger another               
 449         // LauncherModel load.                                                                           
 450         mPaused = false;                                                                                 
 451                                                                                                          
 452         if (PROFILE_STARTUP) {                                                                           
 453             android.os.Debug.startMethodTracing(                                                         
 454                     Environment.getExternalStorageDirectory() + "/launcher");                            
 455         }                                                                                                
 456                                                                                                          
 457         checkForLocaleChange();                                                                          
 458         setContentView(R.layout.launcher);                                                               
 459                                                                                                          
 460         setupViews();                                                                                    
 461         grid.layout(this);                                                                               
 462                                                                                                          
 463         registerContentObservers();                                                                      
 464                                                                                                          
 465         lockAllApps();                                                                                   
 466                                                                                                          
 467         mSavedState = savedInstanceState;                                                                
 468         restoreState(mSavedState);                                                                       
 469                                                                                                          
 470         if (PROFILE_STARTUP) {                                                                           
 471             android.os.Debug.stopMethodTracing();                                                        
 472         }                                                                                                
 473                                                                                                          
 474         if (!mRestoring) {                                                                               
 475             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 476                 // If the user leaves launcher, then we should just load items asynchronously when       
 477                 // they return.                                                                          
 478                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 479             } else {                                                                                     
 480                 // We only load the page synchronously if the user rotates (or triggers a                
 481                 // configuration change) while launcher is in the foreground                             
 482                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 483             }                                                                                            
 484         }                                                                                                
 485                                                                                                          
 486         // For handling default keys                                                                     
 487         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 488         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 489                                                                                                          
 490         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 491         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 492                                                                                                          
 493         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 494         unlockScreenOrientation(true);                                                                   
 495                                                                                                          
 496         if (mLauncherCallbacks != null) {                                                                
 497             mLauncherCallbacks.onCreate(savedInstanceState);                                             
 498             if (mLauncherCallbacks.hasLauncherOverlay()) {                                               
 499                 ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                     
 500                 mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                      
 501                 mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                            
 502                         mLauncherOverlayContainer, mLauncherOverlayCallbacks);                           
 503                 mWorkspace.setLauncherOverlay(mLauncherOverlay);                                         
 504             }                                                                                            
 505         }                                                                                                
 506                                                                                                          
 507         if (shouldShowIntroScreen()) {                                                                   
 508             showIntroScreen();                                                                           
 509         } else {                                                                                         
 510             showFirstRunActivity();                                                                      
 511             showFirstRunClings();                                                                        
 512         }                                                                                                
 513     }                                                                                                    
 514                                                                                                          
 515     private LauncherCallbacks mLauncherCallbacks;                                                        
 516                                                                                                          
 517     public void onPostCreate(Bundle savedInstanceState) {                                                
 518         super.onPostCreate(savedInstanceState);                                                          
 519         if (mLauncherCallbacks != null) {                                                                
 520             mLauncherCallbacks.onPostCreate(savedInstanceState);                                         
 521         }                                                                                                
 522     }                                                                                                    
 523                                                                                                          
 524     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                   
 525         mLauncherCallbacks = callbacks;                                                                  
 526         mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {                
 527             @Override                                                                                    
 528             public void onAllAppsBoundsChanged(Rect bounds) {                                            
 529                 mAppsView.setFixedBounds(Launcher.this, bounds);                                         
 530             }                                                                                            
 531                                                                                                          
 532             @Override                                                                                    
 533             public void dismissAllApps() {                                                               
 534         showWorkspace(true);                                                                             
 535     }                                                                                                    
 536         });                                                                                              
 537         return true;                                                                                     
 538     }                                                                                                    
 539                                                                                                          
 540     @Override                                                                                            
 541     public void onLauncherProviderChange() {                                                             
 542         if (mLauncherCallbacks != null) {                                                                
 543             mLauncherCallbacks.onLauncherProviderChange();                                               
 544         }                                                                                                
 545     }                                                                                                    
 546                                                                                                          
 547     /** To be overridden by subclasses to hint to Launcher that we have custom content */                
 548     protected boolean hasCustomContentToLeft() {                                                         
 549         if (mLauncherCallbacks != null) {                                                                
 550             return mLauncherCallbacks.hasCustomContentToLeft();                                          
 551         }                                                                                                
 552         return false;                                                                                    
 553     }                                                                                                    
 554                                                                                                          
 555     /**                                                                                                  
 556      * To be overridden by subclasses to populate the custom content container and call                  
 557      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 558      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 559      */                                                                                                  
 560     protected void populateCustomContentContainer() {                                                    
 561         if (mLauncherCallbacks != null) {                                                                
 562             mLauncherCallbacks.populateCustomContentContainer();                                         
 563         }                                                                                                
 564     }                                                                                                    
 565                                                                                                          
 566     /**                                                                                                  
 567      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 568      * ensure the custom content page is added or removed if necessary.                                  
 569      */                                                                                                  
 570     protected void invalidateHasCustomContentToLeft() {                                                  
 571         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 572             // Not bound yet, wait for bindScreens to be called.                                         
 573             return;                                                                                      
 574         }                                                                                                
 575                                                                                                          
 576         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 577             // Create the custom content page and call the subclass to populate it.                      
 578             mWorkspace.createCustomContentContainer();                                                   
 579             populateCustomContentContainer();                                                            
 580         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 581             mWorkspace.removeCustomContentPage();                                                        
 582         }                                                                                                
 583     }                                                                                                    
 584                                                                                                          
 585     @Thunk void checkForLocaleChange() {                                                                 
 586         if (sLocaleConfiguration == null) {                                                              
 587             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 588                 @Override                                                                                
 589                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 590                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 591                     readConfiguration(Launcher.this, localeConfiguration);                               
 592                     return localeConfiguration;                                                          
 593                 }                                                                                        
 594                                                                                                          
 595                 @Override                                                                                
 596                 protected void onPostExecute(LocaleConfiguration result) {                               
 597                     sLocaleConfiguration = result;                                                       
 598                     checkForLocaleChange();  // recursive, but now with a locale configuration           
 599                 }                                                                                        
 600             }.execute();                                                                                 
 601             return;                                                                                      
 602         }                                                                                                
 603                                                                                                          
 604         final Configuration configuration = getResources().getConfiguration();                           
 605                                                                                                          
 606         final String previousLocale = sLocaleConfiguration.locale;                                       
 607         final String locale = configuration.locale.toString();                                           
 608                                                                                                          
 609         final int previousMcc = sLocaleConfiguration.mcc;                                                
 610         final int mcc = configuration.mcc;                                                               
 611                                                                                                          
 612         final int previousMnc = sLocaleConfiguration.mnc;                                                
 613         final int mnc = configuration.mnc;                                                               
 614                                                                                                          
 615         boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMn🔵
 616                                                                                                          
 617         if (localeChanged) {                                                                             
 618             sLocaleConfiguration.locale = locale;                                                        
 619             sLocaleConfiguration.mcc = mcc;                                                              
 620             sLocaleConfiguration.mnc = mnc;                                                              
 621                                                                                                          
 622             mIconCache.flush();                                                                          
 623                                                                                                          
 624             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 625             new AsyncTask<Void, Void, Void>() {                                                          
 626                 public Void doInBackground(Void ... args) {                                              
 627                     writeConfiguration(Launcher.this, localeConfiguration);                              
 628                     return null;                                                                         
 629                 }                                                                                        
 630             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
 631         }                                                                                                
 632     }                                                                                                    
 633                                                                                                          
 634     @Thunk static class LocaleConfiguration {                                                            
 635         public String locale;                                                                            
 636         public int mcc = -1;                                                                             
 637         public int mnc = -1;                                                                             
 638     }                                                                                                    
 639                                                                                                          
 640     @Thunk static void readConfiguration(Context context, LocaleConfiguration configuration) {           
 641         DataInputStream in = null;                                                                       
 642         try {                                                                                            
 643             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));         
 644             configuration.locale = in.readUTF();                                                         
 645             configuration.mcc = in.readInt();                                                            
 646             configuration.mnc = in.readInt();                                                            
 647         } catch (FileNotFoundException e) {                                                              
 648             // Ignore                                                                                    
 649         } catch (IOException e) {                                                                        
 650             // Ignore                                                                                    
 651         } finally {                                                                                      
 652             if (in != null) {                                                                            
 653                 try {                                                                                    
 654                     in.close();                                                                          
 655                 } catch (IOException e) {                                                                
 656                     // Ignore                                                                            
 657                 }                                                                                        
 658             }                                                                                            
 659         }                                                                                                
 660     }                                                                                                    
 661                                                                                                          
 662     @Thunk static void writeConfiguration(Context context, LocaleConfiguration configuration) {          
 663         DataOutputStream out = null;                                                                     
 664         try {                                                                                            
 665             out = new DataOutputStream(context.openFileOutput(                                           
 666                     LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                  
 667             out.writeUTF(configuration.locale);                                                          
 668             out.writeInt(configuration.mcc);                                                             
 669             out.writeInt(configuration.mnc);                                                             
 670             out.flush();                                                                                 
 671         } catch (FileNotFoundException e) {                                                              
 672             // Ignore                                                                                    
 673         } catch (IOException e) {                                                                        
 674             //noinspection ResultOfMethodCallIgnored                                                     
 675             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                      
 676         } finally {                                                                                      
 677             if (out != null) {                                                                           
 678                 try {                                                                                    
 679                     out.close();                                                                         
 680                 } catch (IOException e) {                                                                
 681                     // Ignore                                                                            
 682                 }                                                                                        
 683             }                                                                                            
 684         }                                                                                                
 685     }                                                                                                    
 686                                                                                                          
 687     public Stats getStats() {                                                                            
 688         return mStats;                                                                                   
 689     }                                                                                                    
 690                                                                                                          
 691     public LayoutInflater getInflater() {                                                                
 692         return mInflater;                                                                                
 693     }                                                                                                    
 694                                                                                                          
 695     public boolean isDraggingEnabled() {                                                                 
 696         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 697         // that is subsequently removed from the workspace in startBinding().                            
 698         return !mModel.isLoadingWorkspace();                                                             
 699     }                                                                                                    
 700                                                                                                          
 701     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                       
 702     public static int generateViewId() {                                                                 
 703         if (Build.VERSION.SDK_INT >= 17) {                                                               
 704             return View.generateViewId();                                                                
 705         } else {                                                                                         
 706             // View.generateViewId() is not available. The following fallback logic is a copy            
 707             // of its implementation.                                                                    
 708             for (;;) {                                                                                   
 709                 final int result = sNextGeneratedId.get();                                               
 710                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 711                 int newValue = result + 1;                                                               
 712                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 713                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 714                     return result;                                                                       
 715                 }                                                                                        
 716             }                                                                                            
 717         }                                                                                                
 718     }                                                                                                    
 719                                                                                                          
 720     public int getViewIdForItem(ItemInfo info) {                                                         
 721         // This cast is safe given the > 2B range for int.                                               
 722         int itemId = (int) info.id;                                                                      
 723         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 724             return mItemIdToViewId.get(itemId);                                                          
 725         }                                                                                                
 726         int viewId = generateViewId();                                                                   
 727         mItemIdToViewId.put(itemId, viewId);                                                             
 728         return viewId;                                                                                   
 729     }                                                                                                    
 730                                                                                                          
 731     /**                                                                                                  
 732      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 733      * a configuration step, this allows the proper animations to run after other transitions.           
 734      */                                                                                                  
 735     private long completeAdd(PendingAddArguments args) {                                                 
 736         long screenId = args.screenId;                                                                   
 737         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 738             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 739             // that the drop page actually exists.                                                       
 740             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 741         }                                                                                                
 742                                                                                                          
 743         switch (args.requestCode) {                                                                      
 744             case REQUEST_CREATE_SHORTCUT:                                                                
 745                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 746                         args.cellY);                                                                     
 747                 break;                                                                                   
 748             case REQUEST_CREATE_APPWIDGET:                                                               
 749                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 750                 break;                                                                                   
 751             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 752                 completeRestoreAppWidget(args.appWidgetId);                                              
 753                 break;                                                                                   
 754         }                                                                                                
 755         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 756         // if you turned the screen off and then back while in All Apps, Launcher would not              
 757         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 758         resetAddInfo();                                                                                  
 759         return screenId;                                                                                 
 760     }                                                                                                    
 761                                                                                                          
 762     private void handleActivityResult(                                                                   
 763             final int requestCode, final int resultCode, final Intent data) {                            
 764         // Reset the startActivity waiting flag                                                          
 765         setWaitingForResult(false);                                                                      
 766         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 767         mPendingAddWidgetId = -1;                                                                        
 768                                                                                                          
 769         Runnable exitSpringLoaded = new Runnable() {                                                     
 770             @Override                                                                                    
 771             public void run() {                                                                          
 772                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 773                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 774             }                                                                                            
 775         };                                                                                               
 776                                                                                                          
 777         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 778             final int appWidgetId = data != null ?                                                       
 779                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 780             if (resultCode == RESULT_CANCELED) {                                                         
 781                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 782                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 783                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 784             } else if (resultCode == RESULT_OK) {                                                        
 785                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 786                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 787             }                                                                                            
 788             return;                                                                                      
 789         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 790             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 791                 mWorkspace.exitOverviewMode(false);                                                      
 792             }                                                                                            
 793             return;                                                                                      
 794         }                                                                                                
 795                                                                                                          
 796         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 797                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 798                                                                                                          
 799         final boolean workspaceLocked = isWorkspaceLocked();                                             
 800         // We have special handling for widgets                                                          
 801         if (isWidgetDrop) {                                                                              
 802             final int appWidgetId;                                                                       
 803             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 804                     : -1;                                                                                
 805             if (widgetId < 0) {                                                                          
 806                 appWidgetId = pendingAddWidgetId;                                                        
 807             } else {                                                                                     
 808                 appWidgetId = widgetId;                                                                  
 809             }                                                                                            
 810                                                                                                          
 811             final int result;                                                                            
 812             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 813                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 814                         "returned from the widget configuration activity.");                             
 815                 result = RESULT_CANCELED;                                                                
 816                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 817                 final Runnable onComplete = new Runnable() {                                             
 818                     @Override                                                                            
 819                     public void run() {                                                                  
 820                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 821                     }                                                                                    
 822                 };                                                                                       
 823                 if (workspaceLocked) {                                                                   
 824                     // No need to remove the empty screen if we're mid-binding, as the                   
 825                     // the bind will not add the empty screen.                                           
 826                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 827                 } else {                                                                                 
 828                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 829                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 830                 }                                                                                        
 831             } else {                                                                                     
 832                 if (!workspaceLocked) {                                                                  
 833                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 834                         // When the screen id represents an actual screen (as opposed to a rank)         
 835                         // we make sure that the drop page actually exists.                              
 836                         mPendingAddInfo.screenId =                                                       
 837                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 838                     }                                                                                    
 839                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 840                                                                                                          
 841                     dropLayout.setDropPending(true);                                                     
 842                     final Runnable onComplete = new Runnable() {                                         
 843                         @Override                                                                        
 844                         public void run() {                                                              
 845                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 846                             dropLayout.setDropPending(false);                                            
 847                         }                                                                                
 848                     };                                                                                   
 849                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 850                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 851                 } else {                                                                                 
 852                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 853                             mPendingAddInfo);                                                            
 854                     sPendingAddItem = args;                                                              
 855                 }                                                                                        
 856             }                                                                                            
 857             return;                                                                                      
 858         }                                                                                                
 859                                                                                                          
 860         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 861             if (resultCode == RESULT_OK) {                                                               
 862                 // Update the widget view.                                                               
 863                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 864                         pendingAddWidgetId, mPendingAddInfo);                                            
 865                 if (workspaceLocked) {                                                                   
 866                     sPendingAddItem = args;                                                              
 867                 } else {                                                                                 
 868                     completeAdd(args);                                                                   
 869                 }                                                                                        
 870             }                                                                                            
 871             // Leave the widget in the pending state if the user canceled the configure.                 
 872             return;                                                                                      
 873         }                                                                                                
 874                                                                                                          
 875         // The pattern used here is that a user PICKs a specific application,                            
 876         // which, depending on the target, might need to CREATE the actual target.                       
 877                                                                                                          
 878         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 879         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 880         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 881             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 882                     mPendingAddInfo);                                                                    
 883             if (isWorkspaceLocked()) {                                                                   
 884                 sPendingAddItem = args;                                                                  
 885             } else {                                                                                     
 886                 completeAdd(args);                                                                       
 887                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 888                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 889             }                                                                                            
 890         } else if (resultCode == RESULT_CANCELED) {                                                      
 891             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 892                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 893         }                                                                                                
 894         mDragLayer.clearAnimatedView();                                                                  
 895                                                                                                          
 896     }                                                                                                    
 897                                                                                                          
 898     @Override                                                                                            
 899     protected void onActivityResult(                                                                     
 900             final int requestCode, final int resultCode, final Intent data) {                            
 901         handleActivityResult(requestCode, resultCode, data);                                             
 902         if (mLauncherCallbacks != null) {                                                                
 903             mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                          
 904         }                                                                                                
 905     }                                                                                                    
 906                                                                                                          
 907     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 908             appWidgetId, ItemInfo info) {                                                                
 909         PendingAddArguments args = new PendingAddArguments();                                            
 910         args.requestCode = requestCode;                                                                  
 911         args.intent = data;                                                                              
 912         args.container = info.container;                                                                 
 913         args.screenId = info.screenId;                                                                   
 914         args.cellX = info.cellX;                                                                         
 915         args.cellY = info.cellY;                                                                         
 916         args.appWidgetId = appWidgetId;                                                                  
 917         return args;                                                                                     
 918     }                                                                                                    
 919                                                                                                          
 920     /**                                                                                                  
 921      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
 922      *                                                                                                   
 923      * @param screenId the screen id to check                                                            
 924      * @return the new screen, or screenId if it exists                                                  
 925      */                                                                                                  
 926     private long ensurePendingDropLayoutExists(long screenId) {                                          
 927         CellLayout dropLayout =                                                                          
 928                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
 929         if (dropLayout == null) {                                                                        
 930             // it's possible that the add screen was removed because it was                              
 931             // empty and a re-bind occurred                                                              
 932             mWorkspace.addExtraEmptyScreen();                                                            
 933             return mWorkspace.commitExtraEmptyScreen();                                                  
 934         } else {                                                                                         
 935             return screenId;                                                                             
 936         }                                                                                                
 937     }                                                                                                    
 938                                                                                                          
 939     @Thunk void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                
 940         CellLayout cellLayout =                                                                          
 941                 (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                       
 942         Runnable onCompleteRunnable = null;                                                              
 943         int animationType = 0;                                                                           
 944                                                                                                          
 945         AppWidgetHostView boundWidget = null;                                                            
 946         if (resultCode == RESULT_OK) {                                                                   
 947             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
 948             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                
 949                     mPendingAddWidgetInfo);                                                              
 950             boundWidget = layout;                                                                        
 951             onCompleteRunnable = new Runnable() {                                                        
 952                 @Override                                                                                
 953                 public void run() {                                                                      
 954                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                         
 955                             mPendingAddInfo.screenId, layout, null);                                     
 956                     exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                     
 957                             EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                 
 958                 }                                                                                        
 959             };                                                                                           
 960         } else if (resultCode == RESULT_CANCELED) {                                                      
 961             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
 962             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
 963         }                                                                                                
 964         if (mDragLayer.getAnimatedView() != null) {                                                      
 965             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                    
 966                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                         
 967                     animationType, boundWidget, true);                                                   
 968         } else if (onCompleteRunnable != null) {                                                         
 969             // The animated view may be null in the case of a rotation during widget configuration       
 970             onCompleteRunnable.run();                                                                    
 971         }                                                                                                
 972     }                                                                                                    
 973                                                                                                          
 974     @Override                                                                                            
 975     protected void onStop() {                                                                            
 976         super.onStop();                                                                                  
 977         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
 978                                                                                                          
 979         if (mLauncherCallbacks != null) {                                                                
 980             mLauncherCallbacks.onStop();                                                                 
 981         }                                                                                                
 982     }                                                                                                    
 983                                                                                                          
 984     @Override                                                                                            
 985     protected void onStart() {                                                                           
 986         super.onStart();                                                                                 
 987         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
 988                                                                                                          
 989         if (mLauncherCallbacks != null) {                                                                
 990             mLauncherCallbacks.onStart();                                                                
 991         }                                                                                                
 992     }                                                                                                    
 993                                                                                                          
 994     @Override                                                                                            
 995     protected void onResume() {                                                                          
 996         long startTime = 0;                                                                              
 997         if (DEBUG_RESUME_TIME) {                                                                         
 998             startTime = System.currentTimeMillis();                                                      
 999             Log.v(TAG, "Launcher.onResume()");                                                           
1000         }                                                                                                
1001                                                                                                          
1002         if (mLauncherCallbacks != null) {                                                                
1003             mLauncherCallbacks.preOnResume();                                                            
1004         }                                                                                                
1005                                                                                                          
1006         super.onResume();                                                                                
1007                                                                                                          
1008         // Restore the previous launcher state                                                           
1009         if (mOnResumeState == State.WORKSPACE) {                                                         
1010             showWorkspace(false);                                                                        
1011         } else if (mOnResumeState == State.APPS) {                                                       
1012             showAppsView(false /* animated */, false /* resetListToTop */);                              
1013         } else if (mOnResumeState == State.WIDGETS) {                                                    
1014             showWidgetsView(false, false);                                                               
1015         }                                                                                                
1016         mOnResumeState = State.NONE;                                                                     
1017                                                                                                          
1018         // Background was set to gradient in onPause(), restore to black if in all apps.                 
1019         setWorkspaceBackground(mState == State.WORKSPACE);                                               
1020                                                                                                          
1021         mPaused = false;                                                                                 
1022         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1023             setWorkspaceLoading(true);                                                                   
1024             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
1025             mRestoring = false;                                                                          
1026             mOnResumeNeedsLoad = false;                                                                  
1027         }                                                                                                
1028         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1029             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1030             // execute them here                                                                         
1031             long startTimeCallbacks = 0;                                                                 
1032             if (DEBUG_RESUME_TIME) {                                                                     
1033                 startTimeCallbacks = System.currentTimeMillis();                                         
1034             }                                                                                            
1035                                                                                                          
1036             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1037                 mBindOnResumeCallbacks.get(i).run();                                                     
1038             }                                                                                            
1039             mBindOnResumeCallbacks.clear();                                                              
1040             if (DEBUG_RESUME_TIME) {                                                                     
1041                 Log.d(TAG, "Time spent processing callbacks in onResume: " +                             
1042                     (System.currentTimeMillis() - startTimeCallbacks));                                  
1043             }                                                                                            
1044         }                                                                                                
1045         if (mOnResumeCallbacks.size() > 0) {                                                             
1046             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1047                 mOnResumeCallbacks.get(i).run();                                                         
1048             }                                                                                            
1049             mOnResumeCallbacks.clear();                                                                  
1050         }                                                                                                
1051                                                                                                          
1052         // Reset the pressed state of icons that were locked in the press state while activities         
1053         // were launching                                                                                
1054         if (mWaitingForResume != null) {                                                                 
1055             // Resets the previous workspace icon press state                                            
1056             mWaitingForResume.setStayPressed(false);                                                     
1057         }                                                                                                
1058                                                                                                          
1059         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1060         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1061         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1062         // orientation.                                                                                  
1063         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1064         reinflateQSBIfNecessary();                                                                       
1065                                                                                                          
1066         // Process any items that were added while Launcher was away.                                    
1067         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1068                                                                                                          
1069         if (DEBUG_RESUME_TIME) {                                                                         
1070             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1071         }                                                                                                
1072                                                                                                          
1073         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1074             // If we are resuming and the custom content is the current page, we call onShow().          
1075             // It is also poassible that onShow will instead be called slightly after first layout       
1076             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1077             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1078                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1079             }                                                                                            
1080         }                                                                                                
1081         mWorkspace.updateInteractionForState();                                                          
1082         mWorkspace.onResume();                                                                           
1083                                                                                                          
1084         PackageInstallerCompat.getInstance(this).onResume();                                             
1085                                                                                                          
1086         if (mLauncherCallbacks != null) {                                                                
1087             mLauncherCallbacks.onResume();                                                               
1088         }                                                                                                
1089     }                                                                                                    
1090                                                                                                          
1091     @Override                                                                                            
1092     protected void onPause() {                                                                           
1093         // Ensure that items added to Launcher are queued until Launcher returns                         
1094         InstallShortcutReceiver.enableInstallQueue();                                                    
1095         PackageInstallerCompat.getInstance(this).onPause();                                              
1096                                                                                                          
1097         super.onPause();                                                                                 
1098         mPaused = true;                                                                                  
1099         mDragController.cancelDrag();                                                                    
1100         mDragController.resetLastGestureUpTime();                                                        
1101                                                                                                          
1102         // We call onHide() aggressively. The custom content callbacks should be able to                 
1103         // debounce excess onHide calls.                                                                 
1104         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1105             mWorkspace.getCustomContentCallbacks().onHide();                                             
1106         }                                                                                                
1107                                                                                                          
1108         if (mLauncherCallbacks != null) {                                                                
1109             mLauncherCallbacks.onPause();                                                                
1110         }                                                                                                
1111     }                                                                                                    
1112                                                                                                          
1113     public interface CustomContentCallbacks {                                                            
1114         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1115         // by a onResume or by scrolling otherwise.                                                      
1116         public void onShow(boolean fromResume);                                                          
1117                                                                                                          
1118         // Custom content is completely hidden                                                           
1119         public void onHide();                                                                            
1120                                                                                                          
1121         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1122         public void onScrollProgressChanged(float progress);                                             
1123                                                                                                          
1124         // Indicates whether the user is allowed to scroll away from the custom content.                 
1125         boolean isScrollingAllowed();                                                                    
1126     }                                                                                                    
1127                                                                                                          
1128     public interface LauncherOverlay {                                                                   
1129                                                                                                          
1130         /**                                                                                              
1131          * Touch interaction leading to overscroll has begun                                             
1132          */                                                                                              
1133         public void onScrollInteractionBegin();                                                          
1134                                                                                                          
1135         /**                                                                                              
1136          * Touch interaction related to overscroll has ended                                             
1137          */                                                                                              
1138         public void onScrollInteractionEnd();                                                            
1139                                                                                                          
1140         /**                                                                                              
1141          * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                 
1142          * screen (or in the case of RTL, the rightmost screen).                                         
1143          */                                                                                              
1144         public void onScrollChange(int progress, boolean rtl);                                           
1145                                                                                                          
1146         /**                                                                                              
1147          * Screen has stopped scrolling                                                                  
1148          */                                                                                              
1149         public void onScrollSettled();                                                                   
1150                                                                                                          
1151         /**                                                                                              
1152          * This method can be called by the Launcher in order to force the LauncherOverlay               
1153          * to exit fully immersive mode.                                                                 
1154          */                                                                                              
1155         public void forceExitFullImmersion();                                                            
1156     }                                                                                                    
1157                                                                                                          
1158     public interface LauncherAppsCallbacks {                                                             
1159         /**                                                                                              
1160          * Updates launcher to the available space that AllApps can take so as not to overlap with       
1161          * any other views.                                                                              
1162          */                                                                                              
1163         public void onAllAppsBoundsChanged(Rect bounds);                                                 
1164                                                                                                          
1165         /**                                                                                              
1166          * Called to dismiss all apps if it is showing.                                                  
1167          */                                                                                              
1168         public void dismissAllApps();                                                                    
1169     }                                                                                                    
1170                                                                                                          
1171     public interface LauncherOverlayCallbacks {                                                          
1172         /**                                                                                              
1173          * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,           
1174          * however it doesn't modify any state within the launcher.                                      
1175          */                                                                                              
1176         public boolean canEnterFullImmersion();                                                          
1177                                                                                                          
1178         /**                                                                                              
1179          * Should be called to tell Launcher that the LauncherOverlay will take over interaction,        
1180          * eg. by occupying the full screen and handling all touch events.                               
1181          *                                                                                               
1182          * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this        
1183          *          case, Launcher will modify any necessary state and assumes the overlay is            
1184          *          handling all interaction. If false, the LauncherOverlay should cancel any            
1185          *                                                                                               
1186          */                                                                                              
1187         public boolean enterFullImmersion();                                                             
1188                                                                                                          
1189         /**                                                                                              
1190          * Must be called when exiting fully immersive mode. Indicates to Launcher that it has           
1191          * full control over UI and state.                                                               
1192          */                                                                                              
1193         public void exitFullImmersion();                                                                 
1194     }                                                                                                    
1195                                                                                                          
1196     class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                             
1197                                                                                                          
1198         @Override                                                                                        
1199         public boolean canEnterFullImmersion() {                                                         
1200             return mState == State.WORKSPACE;                                                            
1201         }                                                                                                
1202                                                                                                          
1203         @Override                                                                                        
1204         public boolean enterFullImmersion() {                                                            
1205             if (mState == State.WORKSPACE) {                                                             
1206                 // When fully immersed, disregard any touches which fall through.                        
1207                 mDragLayer.setBlockTouch(true);                                                          
1208                 return true;                                                                             
1209             }                                                                                            
1210             return false;                                                                                
1211         }                                                                                                
1212                                                                                                          
1213         @Override                                                                                        
1214         public void exitFullImmersion() {                                                                
1215             mDragLayer.setBlockTouch(false);                                                             
1216         }                                                                                                
1217     }                                                                                                    
1218                                                                                                          
1219     protected boolean hasSettings() {                                                                    
1220         if (mLauncherCallbacks != null) {                                                                
1221             return mLauncherCallbacks.hasSettings();                                                     
1222         }                                                                                                
1223         return false;                                                                                    
1224     }                                                                                                    
1225                                                                                                          
1226                                                                                                          
1227     public void addToCustomContentPage(View customContent,                                               
1228             CustomContentCallbacks callbacks, String description) {                                      
1229         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1230     }                                                                                                    
1231                                                                                                          
1232     // The custom content needs to offset its content to account for the QSB                             
1233     public int getTopOffsetForCustomContent() {                                                          
1234         return mWorkspace.getPaddingTop();                                                               
1235     }                                                                                                    
1236                                                                                                          
1237     @Override                                                                                            
1238     public Object onRetainNonConfigurationInstance() {                                                   
1239         // Flag the loader to stop early before switching                                                
1240         if (mModel.isCurrentCallbacks(this)) {                                                           
1241             mModel.stopLoader();                                                                         
1242         }                                                                                                
1243         //TODO(hyunyoungs): stop the widgets loader when there is a rotation.                            
1244                                                                                                          
1245         return Boolean.TRUE;                                                                             
1246     }                                                                                                    
1247                                                                                                          
1248     // We can't hide the IME if it was forced open.  So don't bother                                     
1249     @Override                                                                                            
1250     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1251         super.onWindowFocusChanged(hasFocus);                                                            
1252         mHasFocus = hasFocus;                                                                            
1253                                                                                                          
1254         if (mLauncherCallbacks != null) {                                                                
1255             mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                           
1256         }                                                                                                
1257     }                                                                                                    
1258                                                                                                          
1259     private boolean acceptFilter() {                                                                     
1260         final InputMethodManager inputManager = (InputMethodManager)                                     
1261                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1262         return !inputManager.isFullscreenMode();                                                         
1263     }                                                                                                    
1264                                                                                                          
1265     @Override                                                                                            
1266     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1267         final int uniChar = event.getUnicodeChar();                                                      
1268         final boolean handled = super.onKeyDown(keyCode, event);                                         
1269         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1270         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1271             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1272                     keyCode, event);                                                                     
1273             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1274                 // something usable has been typed - start a search                                      
1275                 // the typed text will be retrieved and cleared by                                       
1276                 // showSearchDialog()                                                                    
1277                 // If there are multiple keystrokes before the search dialog takes focus,                
1278                 // onSearchRequested() will be called for every keystroke,                               
1279                 // but it is idempotent, so it's fine.                                                   
1280                 return onSearchRequested();                                                              
1281             }                                                                                            
1282         }                                                                                                
1283                                                                                                          
1284         // Eat the long press event so the keyboard doesn't come up.                                     
1285         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1286             return true;                                                                                 
1287         }                                                                                                
1288                                                                                                          
1289         return handled;                                                                                  
1290     }                                                                                                    
1291                                                                                                          
1292     private String getTypedText() {                                                                      
1293         return mDefaultKeySsb.toString();                                                                
1294     }                                                                                                    
1295                                                                                                          
1296     private void clearTypedText() {                                                                      
1297         mDefaultKeySsb.clear();                                                                          
1298         mDefaultKeySsb.clearSpans();                                                                     
1299         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1300     }                                                                                                    
1301                                                                                                          
1302     /**                                                                                                  
1303      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1304      * State                                                                                             
1305      */                                                                                                  
1306     private static State intToState(int stateOrdinal) {                                                  
1307         State state = State.WORKSPACE;                                                                   
1308         final State[] stateValues = State.values();                                                      
1309         for (int i = 0; i < stateValues.length; i++) {                                                   
1310             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1311                 state = stateValues[i];                                                                  
1312                 break;                                                                                   
1313             }                                                                                            
1314         }                                                                                                
1315         return state;                                                                                    
1316     }                                                                                                    
1317                                                                                                          
1318     /**                                                                                                  
1319      * Restores the previous state, if it exists.                                                        
1320      *                                                                                                   
1321      * @param savedState The previous state.                                                             
1322      */                                                                                                  
1323     @SuppressWarnings("unchecked")                                                                       
1324     private void restoreState(Bundle savedState) {                                                       
1325         if (savedState == null) {                                                                        
1326             return;                                                                                      
1327         }                                                                                                
1328                                                                                                          
1329         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1330         if (state == State.APPS || state == State.WIDGETS) {                                             
1331             mOnResumeState = state;                                                                      
1332         }                                                                                                
1333                                                                                                          
1334         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                              
1335                 PagedView.INVALID_RESTORE_PAGE);                                                         
1336         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1337             mWorkspace.setRestorePage(currentScreen);                                                    
1338         }                                                                                                
1339                                                                                                          
1340         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1341         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1342                                                                                                          
1343         if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                            
1344             mPendingAddInfo.container = pendingAddContainer;                                             
1345             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1346             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1347             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1348             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1349             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1350             AppWidgetProviderInfo info = savedState.getParcelable(                                       
1351                     RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);                                              
1352             mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this, info);          
1353             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1354             setWaitingForResult(true);                                                                   
1355             mRestoring = true;                                                                           
1356         }                                                                                                
1357                                                                                                          
1358         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1359         if (renameFolder) {                                                                              
1360             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1361             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1362             mRestoring = true;                                                                           
1363         }                                                                                                
1364                                                                                                          
1365         mItemIdToViewId = (HashMap<Integer, Integer>)                                                    
1366                 savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                      
1367     }                                                                                                    
1368                                                                                                          
1369     /**                                                                                                  
1370      * Finds all the views we need and configure them properly.                                          
1371      */                                                                                                  
1372     private void setupViews() {                                                                          
1373         final DragController dragController = mDragController;                                           
1374                                                                                                          
1375         mLauncherView = findViewById(R.id.launcher);                                                     
1376         mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                         
1377         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                          
1378         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                
1379         mWorkspace.setPageSwitchListener(this);                                                          
1380         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1381                                                                                                          
1382         mLauncherView.setSystemUiVisibility(                                                             
1383                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);     
1384         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1385                                                                                                          
1386         // Setup the drag layer                                                                          
1387         mDragLayer.setup(this, dragController);                                                          
1388                                                                                                          
1389         // Setup the hotseat                                                                             
1390         mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                 
1391         if (mHotseat != null) {                                                                          
1392             mHotseat.setup(this);                                                                        
1393             mHotseat.setOnLongClickListener(this);                                                       
1394         }                                                                                                
1395                                                                                                          
1396         mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                  
1397         View widgetButton = findViewById(R.id.widget_button);                                            
1398         widgetButton.setOnClickListener(new OnClickListener() {                                          
1399             @Override                                                                                    
1400             public void onClick(View arg0) {                                                             
1401                 if (!mWorkspace.isSwitchingState()) {                                                    
1402                     onClickAddWidgetButton(arg0);                                                        
1403                 }                                                                                        
1404             }                                                                                            
1405         });                                                                                              
1406         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1407                                                                                                          
1408         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1409         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1410             @Override                                                                                    
1411             public void onClick(View arg0) {                                                             
1412                 if (!mWorkspace.isSwitchingState()) {                                                    
1413                     onClickWallpaperPicker(arg0);                                                        
1414                 }                                                                                        
1415             }                                                                                            
1416         });                                                                                              
1417         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1418                                                                                                          
1419         View settingsButton = findViewById(R.id.settings_button);                                        
1420         if (hasSettings()) {                                                                             
1421             settingsButton.setOnClickListener(new OnClickListener() {                                    
1422                 @Override                                                                                
1423                 public void onClick(View arg0) {                                                         
1424                     if (!mWorkspace.isSwitchingState()) {                                                
1425                         onClickSettingsButton(arg0);                                                     
1426                     }                                                                                    
1427                 }                                                                                        
1428             });                                                                                          
1429             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1430         } else {                                                                                         
1431             settingsButton.setVisibility(View.GONE);                                                     
1432         }                                                                                                
1433                                                                                                          
1434         mOverviewPanel.setAlpha(0f);                                                                     
1435                                                                                                          
1436         // Setup the workspace                                                                           
1437         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1438         mWorkspace.setOnLongClickListener(this);                                                         
1439         mWorkspace.setup(dragController);                                                                
1440         dragController.addDragListener(mWorkspace);                                                      
1441                                                                                                          
1442         // Get the search/delete bar                                                                     
1443         mSearchDropTargetBar = (SearchDropTargetBar)                                                     
1444                 mDragLayer.findViewById(R.id.search_drop_target_bar);                                    
1445                                                                                                          
1446         // Setup Apps                                                                                    
1447         mAppsView = (AppsContainerView) findViewById(R.id.apps_view);                                    
1448         if (mLauncherCallbacks != null && mLauncherCallbacks.overrideAllAppsSearch()) {                  
1449             mAppsView.hideSearchBar();                                                                   
1450         }                                                                                                
1451                                                                                                          
1452         // Setup AppsCustomize                                                                           
1453         mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);                           
1454                                                                                                          
1455         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1456         dragController.setDragScoller(mWorkspace);                                                       
1457         dragController.setScrollView(mDragLayer);                                                        
1458         dragController.setMoveTarget(mWorkspace);                                                        
1459         dragController.addDropTarget(mWorkspace);                                                        
1460         if (mSearchDropTargetBar != null) {                                                              
1461             mSearchDropTargetBar.setup(this, dragController);                                            
1462             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
1463         }                                                                                                
1464                                                                                                          
1465         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1466             Log.v(TAG, "adding WeightWatcher");                                                          
1467             mWeightWatcher = new WeightWatcher(this);                                                    
1468             mWeightWatcher.setAlpha(0.5f);                                                               
1469             ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                        
1470                     new FrameLayout.LayoutParams(                                                        
1471                             FrameLayout.LayoutParams.MATCH_PARENT,                                       
1472                             FrameLayout.LayoutParams.WRAP_CONTENT,                                       
1473                             Gravity.BOTTOM)                                                              
1474             );                                                                                           
1475                                                                                                          
1476             boolean show = shouldShowWeightWatcher();                                                    
1477             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1478         }                                                                                                
1479     }                                                                                                    
1480                                                                                                          
1481     /**                                                                                                  
1482      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1483      */                                                                                                  
1484     public void setAllAppsButton(View allAppsButton) {                                                   
1485         mAllAppsButton = allAppsButton;                                                                  
1486     }                                                                                                    
1487                                                                                                          
1488     public View getAllAppsButton() {                                                                     
1489         return mAllAppsButton;                                                                           
1490     }                                                                                                    
1491                                                                                                          
1492     /**                                                                                                  
1493      * Creates a view representing a shortcut.                                                           
1494      *                                                                                                   
1495      * @param info The data structure describing the shortcut.                                           
1496      *                                                                                                   
1497      * @return A View inflated from R.layout.application.                                                
1498      */                                                                                                  
1499     View createShortcut(ShortcutInfo info) {                                                             
1500         return createShortcut(R.layout.application,                                                      
1501                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1502     }                                                                                                    
1503                                                                                                          
1504     /**                                                                                                  
1505      * Creates a view representing a shortcut inflated from the specified resource.                      
1506      *                                                                                                   
1507      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1508      * @param parent The group the shortcut belongs to.                                                  
1509      * @param info The data structure describing the shortcut.                                           
1510      *                                                                                                   
1511      * @return A View inflated from layoutResId.                                                         
1512      */                                                                                                  
1513     public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                   
1514         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1515         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1516         favorite.setOnClickListener(this);                                                               
1517         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1518         return favorite;                                                                                 
1519     }                                                                                                    
1520                                                                                                          
1521     /**                                                                                                  
1522      * Add a shortcut to the workspace.                                                                  
1523      *                                                                                                   
1524      * @param data The intent describing the shortcut.                                                   
1525      * @param cellInfo The position on screen where to create the shortcut.                              
1526      */                                                                                                  
1527     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,              
1528             int cellY) {                                                                                 
1529         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1530         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1531         CellLayout layout = getCellLayout(container, screenId);                                          
1532                                                                                                          
1533         boolean foundCellSpan = false;                                                                   
1534                                                                                                          
1535         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                   
1536         if (info == null) {                                                                              
1537             return;                                                                                      
1538         }                                                                                                
1539         final View view = createShortcut(info);                                                          
1540                                                                                                          
1541         // First we check if we already know the exact location where we want to add this item.          
1542         if (cellX >= 0 && cellY >= 0) {                                                                  
1543             cellXY[0] = cellX;                                                                           
1544             cellXY[1] = cellY;                                                                           
1545             foundCellSpan = true;                                                                        
1546                                                                                                          
1547             // If appropriate, either create a folder or add to an existing folder                       
1548             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,               
1549                     true, null,null)) {                                                                  
1550                 return;                                                                                  
1551             }                                                                                            
1552             DragObject dragObject = new DragObject();                                                    
1553             dragObject.dragInfo = info;                                                                  
1554             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,           
1555                     true)) {                                                                             
1556                 return;                                                                                  
1557             }                                                                                            
1558         } else if (touchXY != null) {                                                                    
1559             // when dragging and dropping, just find the closest free spot                               
1560             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1561             foundCellSpan = (result != null);                                                            
1562         } else {                                                                                         
1563             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1564         }                                                                                                
1565                                                                                                          
1566         if (!foundCellSpan) {                                                                            
1567             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1568             return;                                                                                      
1569         }                                                                                                
1570                                                                                                          
1571         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1]);          
1572                                                                                                          
1573         if (!mRestoring) {                                                                               
1574             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                
1575                     isWorkspaceLocked());                                                                
1576         }                                                                                                
1577     }                                                                                                    
1578                                                                                                          
1579     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1580             int minHeight) {                                                                             
1581         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1582         // We want to account for the extra amount of padding that we are adding to the widget           
1583         // to ensure that it gets the full amount of space that it has requested                         
1584         int requiredWidth = minWidth + padding.left + padding.right;                                     
1585         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1586         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1587     }                                                                                                    
1588                                                                                                          
1589     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1590         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1591     }                                                                                                    
1592                                                                                                          
1593     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1594         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1595     }                                                                                                    
1596                                                                                                          
1597     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1598         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1599     }                                                                                                    
1600                                                                                                          
1601     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1602         return getSpanForWidget(context, info.componentName, info.minResizeWidth,                        
1603                 info.minResizeHeight);                                                                   
1604     }                                                                                                    
1605                                                                                                          
1606     /**                                                                                                  
1607      * Add a widget to the workspace.                                                                    
1608      *                                                                                                   
1609      * @param appWidgetId The app widget id                                                              
1610      */                                                                                                  
1611     @Thunk void completeAddAppWidget(int appWidgetId, long container, long screenId,                     
1612             AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                   
1613                                                                                                          
1614         ItemInfo info = mPendingAddInfo;                                                                 
1615         if (appWidgetInfo == null) {                                                                     
1616             appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                         
1617                     mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                    
1618         }                                                                                                
1619                                                                                                          
1620         if (appWidgetInfo.isCustomWidget) {                                                              
1621             appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                        
1622         }                                                                                                
1623                                                                                                          
1624         LauncherAppWidgetInfo launcherInfo;                                                              
1625         launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                   
1626         launcherInfo.spanX = info.spanX;                                                                 
1627         launcherInfo.spanY = info.spanY;                                                                 
1628         launcherInfo.minSpanX = info.minSpanX;                                                           
1629         launcherInfo.minSpanY = info.minSpanY;                                                           
1630         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1631                                                                                                          
1632         LauncherModel.addItemToDatabase(this, launcherInfo,                                              
1633                 container, screenId, info.cellX, info.cellY);                                            
1634                                                                                                          
1635         if (!mRestoring) {                                                                               
1636             if (hostView == null) {                                                                      
1637                 // Perform actual inflation because we're live                                           
1638                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                     
1639                         appWidgetInfo);                                                                  
1640             } else {                                                                                     
1641                 // The AppWidgetHostView has already been inflated and instantiated                      
1642                 launcherInfo.hostView = hostView;                                                        
1643             }                                                                                            
1644             launcherInfo.hostView.setTag(launcherInfo);                                                  
1645             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1646             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1647                                                                                                          
1648             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,               
1649                     info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());            
1650                                                                                                          
1651             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1652         }                                                                                                
1653         resetAddInfo();                                                                                  
1654     }                                                                                                    
1655                                                                                                          
1656     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1657         @Override                                                                                        
1658         public void onReceive(Context context, Intent intent) {                                          
1659             final String action = intent.getAction();                                                    
1660             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1661                 mUserPresent = false;                                                                    
1662                 mDragLayer.clearAllResizeFrames();                                                       
1663                 updateAutoAdvanceState();                                                                
1664                                                                                                          
1665                 // Reset AllApps to its initial state only if we are not in the middle of                
1666                 // processing a multi-step drop                                                          
1667                 if (mAppsView != null && mWidgetsView != null &&                                         
1668                         mPendingAddInfo.container == ItemInfo.NO_ID) {                                   
1669                     showWorkspace(false);                                                                
1670                 }                                                                                        
1671             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1672                 mUserPresent = true;                                                                     
1673                 updateAutoAdvanceState();                                                                
1674             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1675                 mModel.resetLoadedState(false, true);                                                    
1676                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1677                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                      
1678             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1679                 mModel.resetLoadedState(false, true);                                                    
1680                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                
1681                         LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                        
1682                                 | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                          
1683             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                    
1684                     || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {               
1685                 getModel().forceReload();                                                                
1686             }                                                                                            
1687         }                                                                                                
1688     };                                                                                                   
1689                                                                                                          
1690     @Override                                                                                            
1691     public void onAttachedToWindow() {                                                                   
1692         super.onAttachedToWindow();                                                                      
1693                                                                                                          
1694         // Listen for broadcasts related to user-presence                                                
1695         final IntentFilter filter = new IntentFilter();                                                  
1696         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1697         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1698         // For handling managed profiles                                                                 
1699         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1700         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1701         if (ENABLE_DEBUG_INTENTS) {                                                                      
1702             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1703             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1704         }                                                                                                
1705         registerReceiver(mReceiver, filter);                                                             
1706         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1707         setupTransparentSystemBarsForLmp();                                                              
1708         mAttached = true;                                                                                
1709         mVisible = true;                                                                                 
1710     }                                                                                                    
1711                                                                                                          
1712     /**                                                                                                  
1713      * Sets up transparent navigation and status bars in LMP.                                            
1714      * This method is a no-op for other platform versions.                                               
1715      */                                                                                                  
1716     @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                             
1717     private void setupTransparentSystemBarsForLmp() {                                                    
1718         if (Utilities.isLmpOrAbove()) {                                                                  
1719             Window window = getWindow();                                                                 
1720             window.getAttributes().systemUiVisibility |=                                                 
1721                         (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                               
1722                                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                  
1723                                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                           
1724             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1725                         | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                       
1726             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);               
1727             window.setStatusBarColor(Color.TRANSPARENT);                                                 
1728             window.setNavigationBarColor(Color.TRANSPARENT);                                             
1729         }                                                                                                
1730     }                                                                                                    
1731                                                                                                          
1732     @Override                                                                                            
1733     public void onDetachedFromWindow() {                                                                 
1734         super.onDetachedFromWindow();                                                                    
1735         mVisible = false;                                                                                
1736                                                                                                          
1737         if (mAttached) {                                                                                 
1738             unregisterReceiver(mReceiver);                                                               
1739             mAttached = false;                                                                           
1740         }                                                                                                
1741         updateAutoAdvanceState();                                                                        
1742     }                                                                                                    
1743                                                                                                          
1744     public void onWindowVisibilityChanged(int visibility) {                                              
1745         mVisible = visibility == View.VISIBLE;                                                           
1746         updateAutoAdvanceState();                                                                        
1747         // The following code used to be in onResume, but it turns out onResume is called when           
1748         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1749         // is a more appropriate event to handle                                                         
1750         if (mVisible) {                                                                                  
1751             if (!mWorkspaceLoading) {                                                                    
1752                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1753                 // We want to let Launcher draw itself at least once before we force it to build         
1754                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1755                 // apps is nice and speedy.                                                              
1756                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1757                     private boolean mStarted = false;                                                    
1758                     public void onDraw() {                                                               
1759                         if (mStarted) return;                                                            
1760                         mStarted = true;                                                                 
1761                         // We delay the layer building a bit in order to give                            
1762                         // other message processing a time to run.  In particular                        
1763                         // this avoids a delay in hiding the IME if it was                               
1764                         // currently shown, because doing that may involve                               
1765                         // some communication back with the app.                                         
1766                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1767                         final ViewTreeObserver.OnDrawListener listener = this;                           
1768                         mWorkspace.post(new Runnable() {                                                 
1769                                 public void run() {                                                      
1770                                     if (mWorkspace != null &&                                            
1771                                             mWorkspace.getViewTreeObserver() != null) {                  
1772                                         mWorkspace.getViewTreeObserver().                                
1773                                                 removeOnDrawListener(listener);                          
1774                                     }                                                                    
1775                                 }                                                                        
1776                             });                                                                          
1777                         return;                                                                          
1778                     }                                                                                    
1779                 });                                                                                      
1780             }                                                                                            
1781             clearTypedText();                                                                            
1782         }                                                                                                
1783     }                                                                                                    
1784                                                                                                          
1785     @Thunk void sendAdvanceMessage(long delay) {                                                         
1786         mHandler.removeMessages(ADVANCE_MSG);                                                            
1787         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1788         mHandler.sendMessageDelayed(msg, delay);                                                         
1789         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1790     }                                                                                                    
1791                                                                                                          
1792     @Thunk void updateAutoAdvanceState() {                                                               
1793         boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();           
1794         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1795             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1796             if (autoAdvanceRunning) {                                                                    
1797                 long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;       
1798                 sendAdvanceMessage(delay);                                                               
1799             } else {                                                                                     
1800                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1801                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                
1802                             (System.currentTimeMillis() - mAutoAdvanceSentTime));                        
1803                 }                                                                                        
1804                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1805                 mHandler.removeMessages(0); // Remove messages sent using postDelayed()                  
1806             }                                                                                            
1807         }                                                                                                
1808     }                                                                                                    
1809                                                                                                          
1810     private final Handler mHandler = new Handler() {                                                     
1811         @Override                                                                                        
1812         public void handleMessage(Message msg) {                                                         
1813             if (msg.what == ADVANCE_MSG) {                                                               
1814                 int i = 0;                                                                               
1815                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1816                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1817                     final int delay = mAdvanceStagger * i;                                               
1818                     if (v instanceof Advanceable) {                                                      
1819                        postDelayed(new Runnable() {                                                      
1820                            public void run() {                                                           
1821                                ((Advanceable) v).advance();                                              
1822                            }                                                                             
1823                        }, delay);                                                                        
1824                     }                                                                                    
1825                     i++;                                                                                 
1826                 }                                                                                        
1827                 sendAdvanceMessage(mAdvanceInterval);                                                    
1828             }                                                                                            
1829         }                                                                                                
1830     };                                                                                                   
1831                                                                                                          
1832     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1833         if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                      
1834         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1835         if (v instanceof Advanceable) {                                                                  
1836             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1837             ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                             
1838             updateAutoAdvanceState();                                                                    
1839         }                                                                                                
1840     }                                                                                                    
1841                                                                                                          
1842     void removeWidgetToAutoAdvance(View hostView) {                                                      
1843         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1844             mWidgetsToAdvance.remove(hostView);                                                          
1845             updateAutoAdvanceState();                                                                    
1846         }                                                                                                
1847     }                                                                                                    
1848                                                                                                          
1849     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1850         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1851         launcherInfo.hostView = null;                                                                    
1852     }                                                                                                    
1853                                                                                                          
1854     public void showOutOfSpaceMessage(boolean isHotseatLayout) {                                         
1855         int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);           
1856         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1857     }                                                                                                    
1858                                                                                                          
1859     public DragLayer getDragLayer() {                                                                    
1860         return mDragLayer;                                                                               
1861     }                                                                                                    
1862                                                                                                          
1863     public AppsContainerView getAppsView() {                                                             
1864         return mAppsView;                                                                                
1865     }                                                                                                    
1866                                                                                                          
1867     public WidgetsContainerView getWidgetsView() {                                                       
1868         return mWidgetsView;                                                                             
1869     }                                                                                                    
1870                                                                                                          
1871     public Workspace getWorkspace() {                                                                    
1872         return mWorkspace;                                                                               
1873     }                                                                                                    
1874                                                                                                          
1875     public Hotseat getHotseat() {                                                                        
1876         return mHotseat;                                                                                 
1877     }                                                                                                    
1878                                                                                                          
1879     public ViewGroup getOverviewPanel() {                                                                
1880         return mOverviewPanel;                                                                           
1881     }                                                                                                    
1882                                                                                                          
1883     public SearchDropTargetBar getSearchBar() {                                                          
1884         return mSearchDropTargetBar;                                                                     
1885     }                                                                                                    
1886                                                                                                          
1887     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1888         return mAppWidgetHost;                                                                           
1889     }                                                                                                    
1890                                                                                                          
1891     public LauncherModel getModel() {                                                                    
1892         return mModel;                                                                                   
1893     }                                                                                                    
1894                                                                                                          
1895     protected SharedPreferences getSharedPrefs() {                                                       
1896         return mSharedPrefs;                                                                             
1897     }                                                                                                    
1898                                                                                                          
1899     public void closeSystemDialogs() {                                                                   
1900         getWindow().closeAllPanels();                                                                    
1901                                                                                                          
1902         // Whatever we were doing is hereby canceled.                                                    
1903         setWaitingForResult(false);                                                                      
1904     }                                                                                                    
1905                                                                                                          
1906     @Override                                                                                            
1907     protected void onNewIntent(Intent intent) {                                                          
1908         long startTime = 0;                                                                              
1909         if (DEBUG_RESUME_TIME) {                                                                         
1910             startTime = System.currentTimeMillis();                                                      
1911         }                                                                                                
1912         super.onNewIntent(intent);                                                                       
1913                                                                                                          
1914         // Close the menu                                                                                
1915         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1916             // also will cancel mWaitingForResult.                                                       
1917             closeSystemDialogs();                                                                        
1918                                                                                                          
1919             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                             
1920                     Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                               
1921                     != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                           
1922                                                                                                          
1923             if (mWorkspace == null) {                                                                    
1924                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1925                 return;                                                                                  
1926             }                                                                                            
1927             Folder openFolder = mWorkspace.getOpenFolder();                                              
1928             // In all these cases, only animate if we're already on home                                 
1929             mWorkspace.exitWidgetResizeMode();                                                           
1930                                                                                                          
1931             boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                   
1932                     mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                   
1933             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&             
1934                     openFolder == null && moveToDefaultScreen) {                                         
1935                 mWorkspace.moveToDefaultScreen(true);                                                    
1936             }                                                                                            
1937                                                                                                          
1938             closeFolder();                                                                               
1939             exitSpringLoadedDragMode();                                                                  
1940                                                                                                          
1941             // If we are already on home, then just animate back to the workspace,                       
1942             // otherwise, just wait until onResume to set the state back to Workspace                    
1943             if (alreadyOnHome) {                                                                         
1944                 showWorkspace(true);                                                                     
1945             } else {                                                                                     
1946                 mOnResumeState = State.WORKSPACE;                                                        
1947             }                                                                                            
1948                                                                                                          
1949             final View v = getWindow().peekDecorView();                                                  
1950             if (v != null && v.getWindowToken() != null) {                                               
1951                 InputMethodManager imm = (InputMethodManager)getSystemService(                           
1952                         INPUT_METHOD_SERVICE);                                                           
1953                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1954             }                                                                                            
1955                                                                                                          
1956             // Reset the apps view                                                                       
1957             if (!alreadyOnHome && mAppsView != null) {                                                   
1958                 mAppsView.scrollToTop();                                                                 
1959             }                                                                                            
1960                                                                                                          
1961             // Reset the widgets view                                                                    
1962             if (!alreadyOnHome && mWidgetsView != null) {                                                
1963                 mWidgetsView.scrollToTop();                                                              
1964             }                                                                                            
1965                                                                                                          
1966             if (mLauncherCallbacks != null) {                                                            
1967                 mLauncherCallbacks.onHomeIntent();                                                       
1968             }                                                                                            
1969         }                                                                                                
1970                                                                                                          
1971         if (DEBUG_RESUME_TIME) {                                                                         
1972             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1973         }                                                                                                
1974                                                                                                          
1975         if (mLauncherCallbacks != null) {                                                                
1976             mLauncherCallbacks.onNewIntent(intent);                                                      
1977         }                                                                                                
1978     }                                                                                                    
1979                                                                                                          
1980     @Override                                                                                            
1981     public void onRestoreInstanceState(Bundle state) {                                                   
1982         super.onRestoreInstanceState(state);                                                             
1983         for (int page: mSynchronouslyBoundPages) {                                                       
1984             mWorkspace.restoreInstanceStateForChild(page);                                               
1985         }                                                                                                
1986     }                                                                                                    
1987                                                                                                          
1988     @Override                                                                                            
1989     protected void onSaveInstanceState(Bundle outState) {                                                
1990         if (mWorkspace.getChildCount() > 0) {                                                            
1991             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                
1992                     mWorkspace.getCurrentPageOffsetFromCustomContent());                                 
1993         }                                                                                                
1994         super.onSaveInstanceState(outState);                                                             
1995                                                                                                          
1996         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1997         // We close any open folder since it will not be re-opened, and we need to make sure             
1998         // this state is reflected.                                                                      
1999         closeFolder();                                                                                   
2000                                                                                                          
2001         if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&              
2002                 mWaitingForResult) {                                                                     
2003             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
2004             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
2005             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
2006             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
2007             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
2008             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
2009             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
2010             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
2011         }                                                                                                
2012                                                                                                          
2013         if (mFolderInfo != null && mWaitingForResult) {                                                  
2014             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
2015             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
2016         }                                                                                                
2017                                                                                                          
2018         // Save the current widgets tray?                                                                
2019         // TODO(hyunyoungs)                                                                              
2020         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
2021                                                                                                          
2022         if (mLauncherCallbacks != null) {                                                                
2023             mLauncherCallbacks.onSaveInstanceState(outState);                                            
2024         }                                                                                                
2025     }                                                                                                    
2026                                                                                                          
2027     @Override                                                                                            
2028     public void onDestroy() {                                                                            
2029         super.onDestroy();                                                                               
2030                                                                                                          
2031         // Remove all pending runnables                                                                  
2032         mHandler.removeMessages(ADVANCE_MSG);                                                            
2033         mHandler.removeMessages(0);                                                                      
2034         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2035                                                                                                          
2036         // Stop callbacks from LauncherModel                                                             
2037         LauncherAppState app = (LauncherAppState.getInstance());                                         
2038                                                                                                          
2039         // It's possible to receive onDestroy after a new Launcher activity has                          
2040         // been created. In this case, don't interfere with the new Launcher.                            
2041         if (mModel.isCurrentCallbacks(this)) {                                                           
2042             mModel.stopLoader();                                                                         
2043             app.setLauncher(null);                                                                       
2044         }                                                                                                
2045                                                                                                          
2046         try {                                                                                            
2047             mAppWidgetHost.stopListening();                                                              
2048         } catch (NullPointerException ex) {                                                              
2049             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2050         }                                                                                                
2051         mAppWidgetHost = null;                                                                           
2052                                                                                                          
2053         mWidgetsToAdvance.clear();                                                                       
2054                                                                                                          
2055         TextKeyListener.getInstance().release();                                                         
2056                                                                                                          
2057         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2058         // to prevent leaking Launcher activities on orientation change.                                 
2059         if (mModel != null) {                                                                            
2060             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2061         }                                                                                                
2062                                                                                                          
2063         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2064         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2065                                                                                                          
2066         mDragLayer.clearAllResizeFrames();                                                               
2067         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2068         mWorkspace.removeAllWorkspaceScreens();                                                          
2069         mWorkspace = null;                                                                               
2070         mDragController = null;                                                                          
2071                                                                                                          
2072         LauncherAnimUtils.onDestroyActivity();                                                           
2073                                                                                                          
2074         if (mLauncherCallbacks != null) {                                                                
2075             mLauncherCallbacks.onDestroy();                                                              
2076         }                                                                                                
2077     }                                                                                                    
2078                                                                                                          
2079     public DragController getDragController() {                                                          
2080         return mDragController;                                                                          
2081     }                                                                                                    
2082                                                                                                          
2083     @Override                                                                                            
2084     public void startActivityForResult(Intent intent, int requestCode) {                                 
2085         onStartForResult(requestCode);                                                                   
2086         super.startActivityForResult(intent, requestCode);                                               
2087     }                                                                                                    
2088                                                                                                          
2089     @Override                                                                                            
2090     public void startIntentSenderForResult (IntentSender intent, int requestCode,                        
2091             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {       
2092         onStartForResult(requestCode);                                                                   
2093         try {                                                                                            
2094             super.startIntentSenderForResult(intent, requestCode,                                        
2095                 fillInIntent, flagsMask, flagsValues, extraFlags, options);                              
2096         } catch (IntentSender.SendIntentException e) {                                                   
2097             throw new ActivityNotFoundException();                                                       
2098         }                                                                                                
2099     }                                                                                                    
2100                                                                                                          
2101     private void onStartForResult(int requestCode) {                                                     
2102         if (requestCode >= 0) {                                                                          
2103             setWaitingForResult(true);                                                                   
2104         }                                                                                                
2105     }                                                                                                    
2106                                                                                                          
2107     /**                                                                                                  
2108      * Indicates that we want global search for this activity by setting the globalSearch                
2109      * argument for {@link #startSearch} to true.                                                        
2110      */                                                                                                  
2111     @Override                                                                                            
2112     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2113             Bundle appSearchData, boolean globalSearch) {                                                
2114                                                                                                          
2115         showWorkspace(true);                                                                             
2116                                                                                                          
2117         if (initialQuery == null) {                                                                      
2118             // Use any text typed in the launcher as the initial query                                   
2119             initialQuery = getTypedText();                                                               
2120         }                                                                                                
2121         if (appSearchData == null) {                                                                     
2122             appSearchData = new Bundle();                                                                
2123             appSearchData.putString("source", "launcher-search");                                        
2124         }                                                                                                
2125         Rect sourceBounds = new Rect();                                                                  
2126         if (mSearchDropTargetBar != null) {                                                              
2127             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2128         }                                                                                                
2129                                                                                                          
2130         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2131                 appSearchData, sourceBounds);                                                            
2132         if (clearTextImmediately) {                                                                      
2133             clearTypedText();                                                                            
2134         }                                                                                                
2135     }                                                                                                    
2136                                                                                                          
2137     /**                                                                                                  
2138      * Start a text search.                                                                              
2139      *                                                                                                   
2140      * @return {@code true} if the search will start immediately, so any further keypresses              
2141      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2142      * to buffer keypresses.                                                                             
2143      */                                                                                                  
2144     public boolean startSearch(String initialQuery,                                                      
2145             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2146         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
2147             return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,       
2148                     sourceBounds);                                                                       
2149         }                                                                                                
2150                                                                                                          
2151         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2152                 appSearchData, sourceBounds);                                                            
2153         return false;                                                                                    
2154     }                                                                                                    
2155                                                                                                          
2156     /**                                                                                                  
2157      * Starts the global search activity. This code is a copied from SearchManager                       
2158      */                                                                                                  
2159     private void startGlobalSearch(String initialQuery,                                                  
2160             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2161         final SearchManager searchManager =                                                              
2162             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2163         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2164         if (globalSearchActivity == null) {                                                              
2165             Log.w(TAG, "No global search activity found.");                                              
2166             return;                                                                                      
2167         }                                                                                                
2168         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2169         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2170         intent.setComponent(globalSearchActivity);                                                       
2171         // Make sure that we have a Bundle to put source in                                              
2172         if (appSearchData == null) {                                                                     
2173             appSearchData = new Bundle();                                                                
2174         } else {                                                                                         
2175             appSearchData = new Bundle(appSearchData);                                                   
2176         }                                                                                                
2177         // Set source to package name of app that starts global search if not set already.               
2178         if (!appSearchData.containsKey("source")) {                                                      
2179             appSearchData.putString("source", getPackageName());                                         
2180         }                                                                                                
2181         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2182         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2183             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2184         }                                                                                                
2185         if (selectInitialQuery) {                                                                        
2186             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2187         }                                                                                                
2188         intent.setSourceBounds(sourceBounds);                                                            
2189         try {                                                                                            
2190             startActivity(intent);                                                                       
2191         } catch (ActivityNotFoundException ex) {                                                         
2192             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2193         }                                                                                                
2194     }                                                                                                    
2195                                                                                                          
2196     public boolean isOnCustomContent() {                                                                 
2197         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2198     }                                                                                                    
2199                                                                                                          
2200     @Override                                                                                            
2201     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2202         super.onPrepareOptionsMenu(menu);                                                                
2203         if (!isOnCustomContent()) {                                                                      
2204             // Close any open folders                                                                    
2205             closeFolder();                                                                               
2206             // Stop resizing any widgets                                                                 
2207             mWorkspace.exitWidgetResizeMode();                                                           
2208             if (!mWorkspace.isInOverviewMode()) {                                                        
2209                 // Show the overview mode                                                                
2210                 showOverviewMode(true);                                                                  
2211             } else {                                                                                     
2212                 showWorkspace(true);                                                                     
2213             }                                                                                            
2214         }                                                                                                
2215         if (mLauncherCallbacks != null) {                                                                
2216             return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                        
2217         }                                                                                                
2218                                                                                                          
2219         return false;                                                                                    
2220     }                                                                                                    
2221                                                                                                          
2222     @Override                                                                                            
2223     public boolean onSearchRequested() {                                                                 
2224         startSearch(null, false, null, true);                                                            
2225         // Use a custom animation for launching search                                                   
2226         return true;                                                                                     
2227     }                                                                                                    
2228                                                                                                          
2229     public boolean isWorkspaceLocked() {                                                                 
2230         return mWorkspaceLoading || mWaitingForResult;                                                   
2231     }                                                                                                    
2232                                                                                                          
2233     public boolean isWorkspaceLoading() {                                                                
2234         return mWorkspaceLoading;                                                                        
2235     }                                                                                                    
2236                                                                                                          
2237     private void setWorkspaceLoading(boolean value) {                                                    
2238         boolean isLocked = isWorkspaceLocked();                                                          
2239         mWorkspaceLoading = value;                                                                       
2240         if (isLocked != isWorkspaceLocked()) {                                                           
2241             onWorkspaceLockedChanged();                                                                  
2242         }                                                                                                
2243     }                                                                                                    
2244                                                                                                          
2245     private void setWaitingForResult(boolean value) {                                                    
2246         boolean isLocked = isWorkspaceLocked();                                                          
2247         mWaitingForResult = value;                                                                       
2248         if (isLocked != isWorkspaceLocked()) {                                                           
2249             onWorkspaceLockedChanged();                                                                  
2250         }                                                                                                
2251     }                                                                                                    
2252                                                                                                          
2253     protected void onWorkspaceLockedChanged() {                                                          
2254         if (mLauncherCallbacks != null) {                                                                
2255             mLauncherCallbacks.onWorkspaceLockedChanged();                                               
2256         }                                                                                                
2257     }                                                                                                    
2258                                                                                                          
2259     private void resetAddInfo() {                                                                        
2260         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2261         mPendingAddInfo.screenId = -1;                                                                   
2262         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2263         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2264         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2265         mPendingAddInfo.dropPos = null;                                                                  
2266     }                                                                                                    
2267                                                                                                          
2268     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                              
2269             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {          
2270         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2271     }                                                                                                    
2272                                                                                                          
2273     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2274             final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,      
2275             int delay) {                                                                                 
2276         if (appWidgetInfo.configure != null) {                                                           
2277             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2278             mPendingAddWidgetId = appWidgetId;                                                           
2279                                                                                                          
2280             // Launch over to configure widget, if needed                                                
2281             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2282                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2283                                                                                                          
2284         } else {                                                                                         
2285             // Otherwise just add it                                                                     
2286             Runnable onComplete = new Runnable() {                                                       
2287                 @Override                                                                                
2288                 public void run() {                                                                      
2289                     // Exit spring loaded mode if necessary after adding the widget                      
2290                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2291                             null);                                                                       
2292                 }                                                                                        
2293             };                                                                                           
2294             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2295                     appWidgetInfo);                                                                      
2296             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2297         }                                                                                                
2298     }                                                                                                    
2299                                                                                                          
2300     protected void moveToCustomContentScreen(boolean animate) {                                          
2301         // Close any folders that may be open.                                                           
2302         closeFolder();                                                                                   
2303         mWorkspace.moveToCustomContentScreen(animate);                                                   
2304     }                                                                                                    
2305                                                                                                          
2306     public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                   
2307             int[] cell, int spanX, int spanY) {                                                          
2308         switch (info.itemType) {                                                                         
2309             case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                  
2310             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                         
2311                 int span[] = new int[2];                                                                 
2312                 span[0] = spanX;                                                                         
2313                 span[1] = spanY;                                                                         
2314                 addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                        
2315                         container, screenId, cell, span);                                                
2316                 break;                                                                                   
2317             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                          
2318                 processShortcutFromDrop(info.componentName, container, screenId, cell);                  
2319                 break;                                                                                   
2320             default:                                                                                     
2321                 throw new IllegalStateException("Unknown item type: " + info.itemType);                  
2322             }                                                                                            
2323     }                                                                                                    
2324                                                                                                          
2325     /**                                                                                                  
2326      * Process a shortcut drop.                                                                          
2327      *                                                                                                   
2328      * @param componentName The name of the component                                                    
2329      * @param screenId The ID of the screen where it should be added                                     
2330      * @param cell The cell it should be added to, optional                                              
2331      */                                                                                                  
2332     private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,     
2333             int[] cell) {                                                                                
2334         resetAddInfo();                                                                                  
2335         mPendingAddInfo.container = container;                                                           
2336         mPendingAddInfo.screenId = screenId;                                                             
2337         mPendingAddInfo.dropPos = null;                                                                  
2338                                                                                                          
2339         if (cell != null) {                                                                              
2340             mPendingAddInfo.cellX = cell[0];                                                             
2341             mPendingAddInfo.cellY = cell[1];                                                             
2342         }                                                                                                
2343                                                                                                          
2344         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2345         createShortcutIntent.setComponent(componentName);                                                
2346         processShortcut(createShortcutIntent);                                                           
2347     }                                                                                                    
2348                                                                                                          
2349     /**                                                                                                  
2350      * Process a widget drop.                                                                            
2351      *                                                                                                   
2352      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2353      * @param screenId The ID of the screen where it should be added                                     
2354      * @param cell The cell it should be added to, optional                                              
2355      */                                                                                                  
2356     private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,          
2357             int[] cell, int[] span) {                                                                    
2358         resetAddInfo();                                                                                  
2359         mPendingAddInfo.container = info.container = container;                                          
2360         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2361         mPendingAddInfo.dropPos = null;                                                                  
2362         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2363         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2364                                                                                                          
2365         if (cell != null) {                                                                              
2366             mPendingAddInfo.cellX = cell[0];                                                             
2367             mPendingAddInfo.cellY = cell[1];                                                             
2368         }                                                                                                
2369         if (span != null) {                                                                              
2370             mPendingAddInfo.spanX = span[0];                                                             
2371             mPendingAddInfo.spanY = span[1];                                                             
2372         }                                                                                                
2373                                                                                                          
2374         AppWidgetHostView hostView = info.boundWidget;                                                   
2375         int appWidgetId;                                                                                 
2376         if (hostView != null) {                                                                          
2377             appWidgetId = hostView.getAppWidgetId();                                                     
2378             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2379         } else {                                                                                         
2380             // In this case, we either need to start an activity to get permission to bind               
2381             // the widget, or we need to start an activity to configure the widget, or both.             
2382             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2383             Bundle options = info.bindOptions;                                                           
2384                                                                                                          
2385             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
2386                     appWidgetId, info.info, options);                                                    
2387             if (success) {                                                                               
2388                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2389             } else {                                                                                     
2390                 mPendingAddWidgetInfo = info.info;                                                       
2391                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2392                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2393                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2394                 mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                         
2395                     .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);             
2396                 // TODO: we need to make sure that this accounts for the options bundle.                 
2397                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2398                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2399             }                                                                                            
2400         }                                                                                                
2401     }                                                                                                    
2402                                                                                                          
2403     void processShortcut(Intent intent) {                                                                
2404         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2405     }                                                                                                    
2406                                                                                                          
2407     void processWallpaper(Intent intent) {                                                               
2408         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2409     }                                                                                                    
2410                                                                                                          
2411     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,              
2412             int cellY) {                                                                                 
2413         final FolderInfo folderInfo = new FolderInfo();                                                  
2414         folderInfo.title = getText(R.string.folder_name);                                                
2415                                                                                                          
2416         // Update the model                                                                              
2417         LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId,                  
2418                 cellX, cellY);                                                                           
2419         sFolders.put(folderInfo.id, folderInfo);                                                         
2420                                                                                                          
2421         // Create the view                                                                               
2422         FolderIcon newFolder =                                                                           
2423             FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);              
2424         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                       
2425                 isWorkspaceLocked());                                                                    
2426         // Force measure the new folder icon                                                             
2427         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2428         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2429         return newFolder;                                                                                
2430     }                                                                                                    
2431                                                                                                          
2432     void removeFolder(FolderInfo folder) {                                                               
2433         sFolders.remove(folder.id);                                                                      
2434     }                                                                                                    
2435                                                                                                          
2436     /**                                                                                                  
2437      * Registers various content observers. The current implementation registers                         
2438      * only a favorites observer to keep track of the favorites applications.                            
2439      */                                                                                                  
2440     private void registerContentObservers() {                                                            
2441         ContentResolver resolver = getContentResolver();                                                 
2442         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2443                 true, mWidgetObserver);                                                                  
2444     }                                                                                                    
2445                                                                                                          
2446     @Override                                                                                            
2447     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2448         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2449             switch (event.getKeyCode()) {                                                                
2450                 case KeyEvent.KEYCODE_HOME:                                                              
2451                     return true;                                                                         
2452                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2453                     if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                              
2454                         dumpState();                                                                     
2455                         return true;                                                                     
2456                     }                                                                                    
2457                     break;                                                                               
2458             }                                                                                            
2459         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2460             switch (event.getKeyCode()) {                                                                
2461                 case KeyEvent.KEYCODE_HOME:                                                              
2462                     return true;                                                                         
2463             }                                                                                            
2464         }                                                                                                
2465                                                                                                          
2466         return super.dispatchKeyEvent(event);                                                            
2467     }                                                                                                    
2468                                                                                                          
2469     @Override                                                                                            
2470     public void onBackPressed() {                                                                        
2471         if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                      
2472             return;                                                                                      
2473         }                                                                                                
2474                                                                                                          
2475         LauncherAccessibilityDelegate delegate =                                                         
2476                 LauncherAppState.getInstance().getAccessibilityDelegate();                               
2477         if (delegate != null && delegate.onBackPressed()) {                                              
2478             return;                                                                                      
2479             }                                                                                            
2480                                                                                                          
2481         if (isAppsViewVisible()) {                                                                       
2482             showWorkspace(true);                                                                         
2483         } else if (isWidgetsViewVisible())  {                                                            
2484             showOverviewMode(true);                                                                      
2485         } else if (mWorkspace.isInOverviewMode()) {                                                      
2486             mWorkspace.exitOverviewMode(true);                                                           
2487         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2488             Folder openFolder = mWorkspace.getOpenFolder();                                              
2489             if (openFolder.isEditingName()) {                                                            
2490                 openFolder.dismissEditingName();                                                         
2491             } else {                                                                                     
2492                 closeFolder();                                                                           
2493             }                                                                                            
2494         } else {                                                                                         
2495             mWorkspace.exitWidgetResizeMode();                                                           
2496                                                                                                          
2497             // Back button is a no-op here, but give at least some feedback for the button press         
2498             mWorkspace.showOutlinesTemporarily();                                                        
2499         }                                                                                                
2500     }                                                                                                    
2501                                                                                                          
2502     /**                                                                                                  
2503      * Re-listen when widgets are reset.                                                                 
2504      */                                                                                                  
2505     @Thunk void onAppWidgetReset() {                                                                     
2506         if (mAppWidgetHost != null) {                                                                    
2507             mAppWidgetHost.startListening();                                                             
2508         }                                                                                                
2509     }                                                                                                    
2510                                                                                                          
2511     /**                                                                                                  
2512      * Launches the intent referred by the clicked shortcut.                                             
2513      *                                                                                                   
2514      * @param v The view representing the clicked shortcut.                                              
2515      */                                                                                                  
2516     public void onClick(View v) {                                                                        
2517         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2518         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2519         if (v.getWindowToken() == null) {                                                                
2520             return;                                                                                      
2521         }                                                                                                
2522                                                                                                          
2523         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2524             return;                                                                                      
2525         }                                                                                                
2526                                                                                                          
2527         if (v instanceof Workspace) {                                                                    
2528             if (mWorkspace.isInOverviewMode()) {                                                         
2529                 mWorkspace.exitOverviewMode(true);                                                       
2530             }                                                                                            
2531             return;                                                                                      
2532         }                                                                                                
2533                                                                                                          
2534         if (v instanceof CellLayout) {                                                                   
2535             if (mWorkspace.isInOverviewMode()) {                                                         
2536                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2537             }                                                                                            
2538         }                                                                                                
2539                                                                                                          
2540         Object tag = v.getTag();                                                                         
2541         if (tag instanceof ShortcutInfo) {                                                               
2542             onClickAppShortcut(v);                                                                       
2543         } else if (tag instanceof FolderInfo) {                                                          
2544             if (v instanceof FolderIcon) {                                                               
2545                 onClickFolderIcon(v);                                                                    
2546             }                                                                                            
2547         } else if (v == mAllAppsButton) {                                                                
2548             onClickAllAppsButton(v);                                                                     
2549         } else if (tag instanceof AppInfo) {                                                             
2550             startAppShortcutOrInfoActivity(v);                                                           
2551         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2552             if (v instanceof PendingAppWidgetHostView) {                                                 
2553                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2554             }                                                                                            
2555         }                                                                                                
2556     }                                                                                                    
2557                                                                                                          
2558     public void onClickPagedViewIcon(View v) {                                                           
2559         startAppShortcutOrInfoActivity(v);                                                               
2560         if (mLauncherCallbacks != null) {                                                                
2561             mLauncherCallbacks.onClickPagedViewIcon(v);                                                  
2562         }                                                                                                
2563     }                                                                                                    
2564                                                                                                          
2565     public boolean onTouch(View v, MotionEvent event) {                                                  
2566         return false;                                                                                    
2567     }                                                                                                    
2568                                                                                                          
2569     /**                                                                                                  
2570      * Event handler for the app widget view which has not fully restored.                               
2571      */                                                                                                  
2572     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2573         if (mIsSafeModeEnabled) {                                                                        
2574             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2575             return;                                                                                      
2576         }                                                                                                
2577                                                                                                          
2578         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2579         if (v.isReadyForClickSetup()) {                                                                  
2580             int widgetId = info.appWidgetId;                                                             
2581             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2582             if (appWidgetInfo != null) {                                                                 
2583                 mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                  
2584                         this, appWidgetInfo);                                                            
2585                 mPendingAddInfo.copyFrom(info);                                                          
2586                 mPendingAddWidgetId = widgetId;                                                          
2587                                                                                                          
2588                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2589                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2590             }                                                                                            
2591         } else if (info.installProgress < 0) {                                                           
2592             // The install has not been queued                                                           
2593             final String packageName = info.providerName.getPackageName();                               
2594             showBrokenAppInstallDialog(packageName,                                                      
2595                 new DialogInterface.OnClickListener() {                                                  
2596                     public void onClick(DialogInterface dialog, int id) {                                
2597                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2598                     }                                                                                    
2599                 });                                                                                      
2600         } else {                                                                                         
2601             // Download has started.                                                                     
2602             final String packageName = info.providerName.getPackageName();                               
2603             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2604         }                                                                                                
2605     }                                                                                                    
2606                                                                                                          
2607     /**                                                                                                  
2608      * Event handler for the "grid" button that appears on the home screen, which                        
2609      * enters all apps mode.                                                                             
2610      *                                                                                                   
2611      * @param v The view that was clicked.                                                               
2612      */                                                                                                  
2613     protected void onClickAllAppsButton(View v) {                                                        
2614         if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                    
2615         if (isAppsViewVisible()) {                                                                       
2616             showWorkspace(true);                                                                         
2617         } else {                                                                                         
2618             showAppsView(true /* animated */, false /* resetListToTop */);                               
2619         }                                                                                                
2620     }                                                                                                    
2621                                                                                                          
2622     private void showBrokenAppInstallDialog(final String packageName,                                    
2623             DialogInterface.OnClickListener onSearchClickListener) {                                     
2624         new AlertDialog.Builder(this)                                                                    
2625             .setTitle(R.string.abandoned_promises_title)                                                 
2626             .setMessage(R.string.abandoned_promise_explanation)                                          
2627             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2628             .setNeutralButton(R.string.abandoned_clean_this,                                             
2629                 new DialogInterface.OnClickListener() {                                                  
2630                     public void onClick(DialogInterface dialog, int id) {                                
2631                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2632                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2633                     }                                                                                    
2634                 })                                                                                       
2635             .create().show();                                                                            
2636         return;                                                                                          
2637     }                                                                                                    
2638                                                                                                          
2639     /**                                                                                                  
2640      * Event handler for an app shortcut click.                                                          
2641      *                                                                                                   
2642      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2643      */                                                                                                  
2644     protected void onClickAppShortcut(final View v) {                                                    
2645         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2646         Object tag = v.getTag();                                                                         
2647         if (!(tag instanceof ShortcutInfo)) {                                                            
2648             throw new IllegalArgumentException("Input must be a Shortcut");                              
2649         }                                                                                                
2650                                                                                                          
2651         // Open shortcut                                                                                 
2652         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2653                                                                                                          
2654         if (shortcut.isDisabled != 0) {                                                                  
2655             int error = R.string.activity_not_available;                                                 
2656             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2657                 error = R.string.safemode_shortcut_error;                                                
2658             }                                                                                            
2659             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2660             return;                                                                                      
2661         }                                                                                                
2662                                                                                                          
2663         final Intent intent = shortcut.intent;                                                           
2664                                                                                                          
2665         // Check for special shortcuts                                                                   
2666         if (intent.getComponent() != null) {                                                             
2667             final String shortcutClass = intent.getComponent().getClassName();                           
2668                                                                                                          
2669             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2670                 MemoryDumpActivity.startDump(this);                                                      
2671                 return;                                                                                  
2672             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2673                 toggleShowWeightWatcher();                                                               
2674                 return;                                                                                  
2675             }                                                                                            
2676         }                                                                                                
2677                                                                                                          
2678         // Check for abandoned promise                                                                   
2679         if ((v instanceof BubbleTextView)                                                                
2680                 && shortcut.isPromise()                                                                  
2681                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2682             showBrokenAppInstallDialog(                                                                  
2683                     shortcut.getTargetComponent().getPackageName(),                                      
2684                     new DialogInterface.OnClickListener() {                                              
2685                         public void onClick(DialogInterface dialog, int id) {                            
2686                             startAppShortcutOrInfoActivity(v);                                           
2687                         }                                                                                
2688                     });                                                                                  
2689             return;                                                                                      
2690         }                                                                                                
2691                                                                                                          
2692         // Start activities                                                                              
2693         startAppShortcutOrInfoActivity(v);                                                               
2694                                                                                                          
2695         if (mLauncherCallbacks != null) {                                                                
2696             mLauncherCallbacks.onClickAppShortcut(v);                                                    
2697         }                                                                                                
2698     }                                                                                                    
2699                                                                                                          
2700     @Thunk void startAppShortcutOrInfoActivity(View v) {                                                 
2701         Object tag = v.getTag();                                                                         
2702         final ShortcutInfo shortcut;                                                                     
2703         final Intent intent;                                                                             
2704         if (tag instanceof ShortcutInfo) {                                                               
2705             shortcut = (ShortcutInfo) tag;                                                               
2706             intent = shortcut.intent;                                                                    
2707             int[] pos = new int[2];                                                                      
2708             v.getLocationOnScreen(pos);                                                                  
2709             intent.setSourceBounds(new Rect(pos[0], pos[1],                                              
2710                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                     
2711                                                                                                          
2712         } else if (tag instanceof AppInfo) {                                                             
2713             shortcut = null;                                                                             
2714             intent = ((AppInfo) tag).intent;                                                             
2715         } else {                                                                                         
2716             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2717         }                                                                                                
2718                                                                                                          
2719         boolean success = startActivitySafely(v, intent, tag);                                           
2720         mStats.recordLaunch(intent, shortcut);                                                           
2721                                                                                                          
2722         if (success && v instanceof BubbleTextView) {                                                    
2723             mWaitingForResume = (BubbleTextView) v;                                                      
2724             mWaitingForResume.setStayPressed(true);                                                      
2725         }                                                                                                
2726     }                                                                                                    
2727                                                                                                          
2728     /**                                                                                                  
2729      * Event handler for a folder icon click.                                                            
2730      *                                                                                                   
2731      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2732      */                                                                                                  
2733     protected void onClickFolderIcon(View v) {                                                           
2734         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2735         if (!(v instanceof FolderIcon)){                                                                 
2736             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2737         }                                                                                                
2738                                                                                                          
2739         FolderIcon folderIcon = (FolderIcon) v;                                                          
2740         final FolderInfo info = folderIcon.getFolderInfo();                                              
2741         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2742                                                                                                          
2743         // If the folder info reports that the associated folder is open, then verify that               
2744         // it is actually opened. There have been a few instances where this gets out of sync.           
2745         if (info.opened && openFolder == null) {                                                         
2746             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2747                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2748             info.opened = false;                                                                         
2749         }                                                                                                
2750                                                                                                          
2751         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2752             // Close any open folder                                                                     
2753             closeFolder();                                                                               
2754             // Open the requested folder                                                                 
2755             openFolder(folderIcon);                                                                      
2756         } else {                                                                                         
2757             // Find the open folder...                                                                   
2758             int folderScreen;                                                                            
2759             if (openFolder != null) {                                                                    
2760                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2761                 // .. and close it                                                                       
2762                 closeFolder(openFolder);                                                                 
2763                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2764                     // Close any folder open on the current screen                                       
2765                     closeFolder();                                                                       
2766                     // Pull the folder onto this screen                                                  
2767                     openFolder(folderIcon);                                                              
2768                 }                                                                                        
2769             }                                                                                            
2770         }                                                                                                
2771                                                                                                          
2772         if (mLauncherCallbacks != null) {                                                                
2773             mLauncherCallbacks.onClickFolderIcon(v);                                                     
2774         }                                                                                                
2775     }                                                                                                    
2776                                                                                                          
2777     /**                                                                                                  
2778      * Event handler for the (Add) Widgets button that appears after a long press                        
2779      * on the home screen.                                                                               
2780      */                                                                                                  
2781     protected void onClickAddWidgetButton(View view) {                                                   
2782         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                  
2783         if (mIsSafeModeEnabled) {                                                                        
2784             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2785         } else {                                                                                         
2786             showWidgetsView(true /* animated */, true /* resetPageToZero */);                            
2787             if (mLauncherCallbacks != null) {                                                            
2788                 mLauncherCallbacks.onClickAddWidgetButton(view);                                         
2789             }                                                                                            
2790         }                                                                                                
2791     }                                                                                                    
2792                                                                                                          
2793     /**                                                                                                  
2794      * Event handler for the wallpaper picker button that appears after a long press                     
2795      * on the home screen.                                                                               
2796      */                                                                                                  
2797     protected void onClickWallpaperPicker(View v) {                                                      
2798         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                  
2799         startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()),     
2800                 REQUEST_PICK_WALLPAPER);                                                                 
2801                                                                                                          
2802         if (mLauncherCallbacks != null) {                                                                
2803             mLauncherCallbacks.onClickWallpaperPicker(v);                                                
2804         }                                                                                                
2805     }                                                                                                    
2806                                                                                                          
2807     /**                                                                                                  
2808      * Event handler for a click on the settings button that appears after a long press                  
2809      * on the home screen.                                                                               
2810      */                                                                                                  
2811     protected void onClickSettingsButton(View v) {                                                       
2812         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2813         if (mLauncherCallbacks != null) {                                                                
2814             mLauncherCallbacks.onClickSettingsButton(v);                                                 
2815         }                                                                                                
2816     }                                                                                                    
2817                                                                                                          
2818     public void onTouchDownAllAppsButton(View v) {                                                       
2819         // Provide the same haptic feedback that the system offers for virtual keys.                     
2820         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2821     }                                                                                                    
2822                                                                                                          
2823     public void performHapticFeedbackOnTouchDown(View v) {                                               
2824         // Provide the same haptic feedback that the system offers for virtual keys.                     
2825         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2826     }                                                                                                    
2827                                                                                                          
2828     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2829         if (mHapticFeedbackTouchListener == null) {                                                      
2830             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2831                 @Override                                                                                
2832                 public boolean onTouch(View v, MotionEvent event) {                                      
2833                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2834                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2835                     }                                                                                    
2836                     return false;                                                                        
2837                 }                                                                                        
2838             };                                                                                           
2839         }                                                                                                
2840         return mHapticFeedbackTouchListener;                                                             
2841     }                                                                                                    
2842                                                                                                          
2843     public void onDragStarted(View view) {                                                               
2844         if (isOnCustomContent()) {                                                                       
2845             // Custom content screen doesn't participate in drag and drop. If on custom                  
2846             // content screen, move to default.                                                          
2847             moveWorkspaceToDefaultScreen();                                                              
2848         }                                                                                                
2849                                                                                                          
2850         if (mLauncherCallbacks != null) {                                                                
2851             mLauncherCallbacks.onDragStarted(view);                                                      
2852         }                                                                                                
2853     }                                                                                                    
2854                                                                                                          
2855     /**                                                                                                  
2856      * Called when the user stops interacting with the launcher.                                         
2857      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2858      */                                                                                                  
2859     protected void onInteractionEnd() {                                                                  
2860         if (mLauncherCallbacks != null) {                                                                
2861             mLauncherCallbacks.onInteractionEnd();                                                       
2862         }                                                                                                
2863     }                                                                                                    
2864                                                                                                          
2865     /**                                                                                                  
2866      * Called when the user starts interacting with the launcher.                                        
2867      * The possible interactions are:                                                                    
2868      *  - open all apps                                                                                  
2869      *  - reorder an app shortcut, or a widget                                                           
2870      *  - open the overview mode.                                                                        
2871      * This is a good time to stop doing things that only make sense                                     
2872      * when the user is on the homescreen and not doing housekeeping.                                    
2873      */                                                                                                  
2874     protected void onInteractionBegin() {                                                                
2875         if (mLauncherCallbacks != null) {                                                                
2876             mLauncherCallbacks.onInteractionBegin();                                                     
2877         }                                                                                                
2878     }                                                                                                    
2879                                                                                                          
2880     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2881         try {                                                                                            
2882             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2883             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2884         } catch (SecurityException e) {                                                                  
2885             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2886             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2887         } catch (ActivityNotFoundException e) {                                                          
2888             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2889             Log.e(TAG, "Unable to launch settings");                                                     
2890         }                                                                                                
2891     }                                                                                                    
2892                                                                                                          
2893     // returns true if the activity was started                                                          
2894     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2895             UserHandleCompat user) {                                                                     
2896         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2897             // System applications cannot be installed. For now, show a toast explaining that.           
2898             // We may give them the option of disabling apps this way.                                   
2899             int messageId = R.string.uninstall_system_app_text;                                          
2900             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2901             return false;                                                                                
2902         } else {                                                                                         
2903             String packageName = componentName.getPackageName();                                         
2904             String className = componentName.getClassName();                                             
2905             Intent intent = new Intent(                                                                  
2906                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2907             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2908                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2909             if (user != null) {                                                                          
2910                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2911             }                                                                                            
2912             startActivity(intent);                                                                       
2913             return true;                                                                                 
2914         }                                                                                                
2915     }                                                                                                    
2916                                                                                                          
2917     boolean startActivity(View v, Intent intent, Object tag) {                                           
2918         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2919         try {                                                                                            
2920             // Only launch using the new animation if the shortcut has not opted out (this is a          
2921             // private contract between launcher and may be ignored in the future).                      
2922             boolean useLaunchAnimation = (v != null) &&                                                  
2923                     !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                              
2924             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2925             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2926                                                                                                          
2927             UserHandleCompat user = null;                                                                
2928             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2929                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2930                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2931             }                                                                                            
2932                                                                                                          
2933             Bundle optsBundle = null;                                                                    
2934 <<<<<<< MINE                                                                                             
2935             if (useLaunchAnimation) {                                                                    
2936                 ActivityOptions opts = null;                                                             
2937                 if (sClipRevealMethod != null) {                                                         
2938                     // TODO: call method directly when Launcher3 can depend on M APIs                    
2939                     int left = 0, top = 0;                                                               
2940                     int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();                    
2941                     if (v instanceof TextView) {                                                         
2942                         // Launch from center of icon, not entire view                                   
2943                         Drawable icon = Workspace.getTextViewIcon((TextView) v);                         
2944                         if (icon != null) {                                                              
2945                             Rect bounds = icon.getBounds();                                              
2946                             left = (width - bounds.width()) / 2;                                         
2947                             top = v.getPaddingTop();                                                     
2948                             width = bounds.width();                                                      
2949                             height = bounds.height();                                                    
2950                         }                                                                                
2951                     }                                                                                    
2952                     try {                                                                                
2953                         opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,                       
2954                                 left, top, width, height);                                               
2955                     } catch (IllegalAccessException e) {                                                 
2956                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2957                         sClipRevealMethod = null;                                                        
2958                     } catch (InvocationTargetException e) {                                              
2959                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2960                         sClipRevealMethod = null;                                                        
2961                     }                                                                                    
2962                 }                                                                                        
2963                 if (opts == null && !Utilities.isLmpOrAbove()) {                                         
2964                     opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,                                 
2965                                     v.getMeasuredWidth(), v.getMeasuredHeight());                        
2966                 }                                                                                        
2967                 optsBundle = opts != null ? opts.toBundle() : null;                                      
2968 ||||||| BASE                                                                                             
2969             if (useLaunchAnimation) {                                                                    
2970                 ActivityOptions opts = Utilities.isLmpOrAbove() ?                                        
2971                         ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim)🔵
2972                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
2973                 optsBundle = opts.toBundle();                                                            
2974             }                                                                                            
2975                                                                                                          
2976             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
2977                 // Could be launching some bookkeeping activity                                          
2978                 startActivity(intent, optsBundle);                                                       
2979             } else {                                                                                     
2980                 // TODO Component can be null when shortcuts are supported for secondary user            
2981                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
2982                         intent.getSourceBounds(), optsBundle);                                           
2983             }                                                                                            
2984             return true;                                                                                 
2985         } catch (SecurityException e) {                                                                  
2986             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2987             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
2988                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
2989                     "or use the exported attribute for this activity. "                                  
2990                     + "tag="+ tag + " intent=" + intent, e);                                             
2991         }                                                                                                
2992         return false;                                                                                    
2993     }                                                                                                    
2994 =======                                                                                                  
2995             if (useLaunchAnimation && !Utilities.isLmpOrAbove()) {                                       
2996                 // On pre-L devices, we use the scale up transition.                                     
2997                 // Otherwise we use system default.                                                      
2998                 ActivityOptions opts =                                                                   
2999                         ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasured🔵
3000                 optsBundle = opts.toBundle();                                                            
3001 >>>>>>> YOURS                                                                                            
3002             }                                                                                            
3003                                                                                                          
3004             if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                          
3005                 // Could be launching some bookkeeping activity                                          
3006                 startActivity(intent, optsBundle);                                                       
3007             } else {                                                                                     
3008                 // TODO Component can be null when shortcuts are supported for secondary user            
3009                 launcherApps.startActivityForProfile(intent.getComponent(), user,                        
3010                         intent.getSourceBounds(), optsBundle);                                           
3011             }                                                                                            
3012             return true;                                                                                 
3013         } catch (SecurityException e) {                                                                  
3014             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3015             Log.e(TAG, "Launcher does not have the permission to launch " + intent +                     
3016                     ". Make sure to create a MAIN intent-filter for the corresponding activity " +       
3017                     "or use the exported attribute for this activity. "                                  
3018                     + "tag="+ tag + " intent=" + intent, e);                                             
3019         }                                                                                                
3020         return false;                                                                                    
3021     }                                                                                                    
3022                                                                                                          
3023     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
3024         boolean success = false;                                                                         
3025         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
3026             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
3027             return false;                                                                                
3028         }                                                                                                
3029         try {                                                                                            
3030             success = startActivity(v, intent, tag);                                                     
3031         } catch (ActivityNotFoundException e) {                                                          
3032             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
3033             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
3034         }                                                                                                
3035         return success;                                                                                  
3036     }                                                                                                    
3037                                                                                                          
3038     /**                                                                                                  
3039      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
3040      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
3041      */                                                                                                  
3042     private void copyFolderIconToImage(FolderIcon fi) {                                                  
3043         final int width = fi.getMeasuredWidth();                                                         
3044         final int height = fi.getMeasuredHeight();                                                       
3045                                                                                                          
3046         // Lazy load ImageView, Bitmap and Canvas                                                        
3047         if (mFolderIconImageView == null) {                                                              
3048             mFolderIconImageView = new ImageView(this);                                                  
3049         }                                                                                                
3050         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
3051                 mFolderIconBitmap.getHeight() != height) {                                               
3052             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
3053             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
3054         }                                                                                                
3055                                                                                                          
3056         DragLayer.LayoutParams lp;                                                                       
3057         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
3058             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
3059         } else {                                                                                         
3060             lp = new DragLayer.LayoutParams(width, height);                                              
3061         }                                                                                                
3062                                                                                                          
3063         // The layout from which the folder is being opened may be scaled, adjust the starting           
3064         // view size by this scale factor.                                                               
3065         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
3066         lp.customPosition = true;                                                                        
3067         lp.x = mRectForFolderAnimation.left;                                                             
3068         lp.y = mRectForFolderAnimation.top;                                                              
3069         lp.width = (int) (scale * width);                                                                
3070         lp.height = (int) (scale * height);                                                              
3071                                                                                                          
3072         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
3073         fi.draw(mFolderIconCanvas);                                                                      
3074         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
3075         if (fi.getFolder() != null) {                                                                    
3076             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
3077             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
3078         }                                                                                                
3079         // Just in case this image view is still in the drag layer from a previous animation,            
3080         // we remove it and re-add it.                                                                   
3081         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3082             mDragLayer.removeView(mFolderIconImageView);                                                 
3083         }                                                                                                
3084         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3085         if (fi.getFolder() != null) {                                                                    
3086             fi.getFolder().bringToFront();                                                               
3087         }                                                                                                
3088     }                                                                                                    
3089                                                                                                          
3090     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3091         if (fi == null) return;                                                                          
3092         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3093         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3094         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3095                                                                                                          
3096         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3097         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3098             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3099             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3100             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3101         }                                                                                                
3102                                                                                                          
3103         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3104         copyFolderIconToImage(fi);                                                                       
3105         fi.setVisibility(View.INVISIBLE);                                                                
3106                                                                                                          
3107         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3108                 scaleX, scaleY);                                                                         
3109         if (Utilities.isLmpOrAbove()) {                                                                  
3110             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3111         }                                                                                                
3112         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3113         oa.start();                                                                                      
3114     }                                                                                                    
3115                                                                                                          
3116     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3117         if (fi == null) return;                                                                          
3118         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3119         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3120         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3121                                                                                                          
3122         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3123                                                                                                          
3124         // We remove and re-draw the FolderIcon in-case it has changed                                   
3125         mDragLayer.removeView(mFolderIconImageView);                                                     
3126         copyFolderIconToImage(fi);                                                                       
3127         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3128                 scaleX, scaleY);                                                                         
3129         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3130         oa.addListener(new AnimatorListenerAdapter() {                                                   
3131             @Override                                                                                    
3132             public void onAnimationEnd(Animator animation) {                                             
3133                 if (cl != null) {                                                                        
3134                     cl.clearFolderLeaveBehind();                                                         
3135                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3136                     mDragLayer.removeView(mFolderIconImageView);                                         
3137                     fi.setVisibility(View.VISIBLE);                                                      
3138                 }                                                                                        
3139             }                                                                                            
3140         });                                                                                              
3141         oa.start();                                                                                      
3142     }                                                                                                    
3143                                                                                                          
3144     /**                                                                                                  
3145      * Opens the user folder described by the specified tag. The opening of the folder                   
3146      * is animated relative to the specified View. If the View is null, no animation                     
3147      * is played.                                                                                        
3148      *                                                                                                   
3149      * @param folderInfo The FolderInfo describing the folder to open.                                   
3150      */                                                                                                  
3151     public void openFolder(FolderIcon folderIcon) {                                                      
3152         Folder folder = folderIcon.getFolder();                                                          
3153         Folder openFolder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                      
3154         if (openFolder != null && openFolder != folder) {                                                
3155             // Close any open folder before opening a folder.                                            
3156             closeFolder();                                                                               
3157         }                                                                                                
3158                                                                                                          
3159         FolderInfo info = folder.mInfo;                                                                  
3160                                                                                                          
3161         info.opened = true;                                                                              
3162                                                                                                          
3163         // While the folder is open, the position of the icon cannot change.                             
3164         ((CellLayout.LayoutParams) folderIcon.getLayoutParams()).canReorder = false;                     
3165                                                                                                          
3166         // Just verify that the folder hasn't already been added to the DragLayer.                       
3167         // There was a one-off crash where the folder had a parent already.                              
3168         if (folder.getParent() == null) {                                                                
3169             mDragLayer.addView(folder);                                                                  
3170             mDragController.addDropTarget((DropTarget) folder);                                          
3171         } else {                                                                                         
3172             Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                  
3173                     folder.getParent() + ").");                                                          
3174         }                                                                                                
3175         folder.animateOpen();                                                                            
3176         growAndFadeOutFolderIcon(folderIcon);                                                            
3177                                                                                                          
3178         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3179         // the workspace items                                                                           
3180         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3181         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3182     }                                                                                                    
3183                                                                                                          
3184     public void closeFolder() {                                                                          
3185         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3186         if (folder != null) {                                                                            
3187             if (folder.isEditingName()) {                                                                
3188                 folder.dismissEditingName();                                                             
3189             }                                                                                            
3190             closeFolder(folder);                                                                         
3191         }                                                                                                
3192     }                                                                                                    
3193                                                                                                          
3194     void closeFolder(Folder folder) {                                                                    
3195         folder.getInfo().opened = false;                                                                 
3196                                                                                                          
3197         ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                   
3198         if (parent != null) {                                                                            
3199             FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                         
3200             shrinkAndFadeInFolderIcon(fi);                                                               
3201             if (fi != null) {                                                                            
3202                 ((CellLayout.LayoutParams) fi.getLayoutParams()).canReorder = true;                      
3203             }                                                                                            
3204         }                                                                                                
3205         folder.animateClosed();                                                                          
3206                                                                                                          
3207         // Notify the accessibility manager that this folder "window" has disappeard and no              
3208         // longer occludeds the workspace items                                                          
3209         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3210     }                                                                                                    
3211                                                                                                          
3212     public boolean onLongClick(View v) {                                                                 
3213         if (!isDraggingEnabled()) return false;                                                          
3214         if (isWorkspaceLocked()) return false;                                                           
3215         if (mState != State.WORKSPACE) return false;                                                     
3216                                                                                                          
3217         if (v instanceof Workspace) {                                                                    
3218             if (!mWorkspace.isInOverviewMode()) {                                                        
3219                 if (mWorkspace.enterOverviewMode()) {                                                    
3220                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3221                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3222                     return true;                                                                         
3223                 } else {                                                                                 
3224                     return false;                                                                        
3225                 }                                                                                        
3226             } else {                                                                                     
3227                 return false;                                                                            
3228             }                                                                                            
3229         }                                                                                                
3230                                                                                                          
3231         CellLayout.CellInfo longClickCellInfo = null;                                                    
3232         View itemUnderLongClick = null;                                                                  
3233         if (v.getTag() instanceof ItemInfo) {                                                            
3234             ItemInfo info = (ItemInfo) v.getTag();                                                       
3235             longClickCellInfo = new CellLayout.CellInfo(v, info);                                        
3236             itemUnderLongClick = longClickCellInfo.cell;                                                 
3237             resetAddInfo();                                                                              
3238         }                                                                                                
3239                                                                                                          
3240         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3241         // on hotseat items.                                                                             
3242         final boolean inHotseat = isHotseatLayout(v);                                                    
3243         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3244         if (allowLongPress && !mDragController.isDragging()) {                                           
3245             if (itemUnderLongClick == null) {                                                            
3246                 // User long pressed on empty space                                                      
3247                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3248                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3249                 if (mWorkspace.isInOverviewMode()) {                                                     
3250                     mWorkspace.startReordering(v);                                                       
3251                 } else {                                                                                 
3252                     mWorkspace.enterOverviewMode();                                                      
3253                 }                                                                                        
3254             } else {                                                                                     
3255                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3256                         mHotseat.getOrderInHotseat(                                                      
3257                                 longClickCellInfo.cellX,                                                 
3258                                 longClickCellInfo.cellY));                                               
3259                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3260                     // User long pressed on an item                                                      
3261                     mWorkspace.startDrag(longClickCellInfo);                                             
3262                 }                                                                                        
3263             }                                                                                            
3264         }                                                                                                
3265         return true;                                                                                     
3266     }                                                                                                    
3267                                                                                                          
3268     boolean isHotseatLayout(View layout) {                                                               
3269         return mHotseat != null && layout != null &&                                                     
3270                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3271     }                                                                                                    
3272                                                                                                          
3273     /**                                                                                                  
3274      * Returns the CellLayout of the specified container at the specified screen.                        
3275      */                                                                                                  
3276     public CellLayout getCellLayout(long container, long screenId) {                                     
3277         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3278             if (mHotseat != null) {                                                                      
3279                 return mHotseat.getLayout();                                                             
3280             } else {                                                                                     
3281                 return null;                                                                             
3282             }                                                                                            
3283         } else {                                                                                         
3284             return mWorkspace.getScreenWithId(screenId);                                                 
3285         }                                                                                                
3286     }                                                                                                    
3287                                                                                                          
3288     /**                                                                                                  
3289      * For overridden classes.                                                                           
3290      */                                                                                                  
3291     public boolean isAllAppsVisible() {                                                                  
3292         return isAppsViewVisible();                                                                      
3293     }                                                                                                    
3294                                                                                                          
3295     public boolean isAppsViewVisible() {                                                                 
3296         return (mState == State.APPS) || (mOnResumeState == State.APPS);                                 
3297     }                                                                                                    
3298                                                                                                          
3299     public boolean isWidgetsViewVisible() {                                                              
3300         return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                           
3301     }                                                                                                    
3302                                                                                                          
3303     private void setWorkspaceBackground(boolean workspace) {                                             
3304         mLauncherView.setBackground(workspace ?                                                          
3305                 mWorkspaceBackgroundDrawable : null);                                                    
3306     }                                                                                                    
3307                                                                                                          
3308     protected void changeWallpaperVisiblity(boolean visible) {                                           
3309         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3310         int curflags = getWindow().getAttributes().flags                                                 
3311                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3312         if (wpflags != curflags) {                                                                       
3313             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3314         }                                                                                                
3315         setWorkspaceBackground(visible);                                                                 
3316     }                                                                                                    
3317                                                                                                          
3318     @Override                                                                                            
3319     public void onTrimMemory(int level) {                                                                
3320         super.onTrimMemory(level);                                                                       
3321         if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                        
3322             // The widget preview db can result in holding onto over                                     
3323             // 3MB of memory for caching which isn't necessary.                                          
3324             SQLiteDatabase.releaseMemory();                                                              
3325                                                                                                          
3326             // This clears all widget bitmaps from the widget tray                                       
3327             // TODO(hyunyoungs)                                                                          
3328         }                                                                                                
3329         if (mLauncherCallbacks != null) {                                                                
3330             mLauncherCallbacks.onTrimMemory(level);                                                      
3331         }                                                                                                
3332     }                                                                                                    
3333                                                                                                          
3334     @Override                                                                                            
3335     public void onStateTransitionHideSearchBar() {                                                       
3336         // Hide the search bar                                                                           
3337         if (mSearchDropTargetBar != null) {                                                              
3338             mSearchDropTargetBar.hideSearchBar(false /* animated */);                                    
3339         }                                                                                                
3340     }                                                                                                    
3341                                                                                                          
3342     protected void showWorkspace(boolean animated) {                                                     
3343         showWorkspace(animated, null);                                                                   
3344     }                                                                                                    
3345                                                                                                          
3346     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3347         boolean changed = mState != State.WORKSPACE ||                                                   
3348                 mWorkspace.getState() != Workspace.State.NORMAL;                                         
3349         if (changed) {                                                                                   
3350             boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                 
3351             mWorkspace.setVisibility(View.VISIBLE);                                                      
3352             mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,          
3353                     animated, onCompleteRunnable);                                                       
3354                                                                                                          
3355             // Show the search bar (only animate if we were showing the drop target bar in spring        
3356             // loaded mode)                                                                              
3357             if (mSearchDropTargetBar != null) {                                                          
3358                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3359             }                                                                                            
3360                                                                                                          
3361             // Set focus to the AppsCustomize button                                                     
3362             if (mAllAppsButton != null) {                                                                
3363                 mAllAppsButton.requestFocus();                                                           
3364             }                                                                                            
3365         }                                                                                                
3366                                                                                                          
3367         // Change the state *after* we've called all the transition code                                 
3368         mState = State.WORKSPACE;                                                                        
3369                                                                                                          
3370         // Resume the auto-advance of widgets                                                            
3371         mUserPresent = true;                                                                             
3372         updateAutoAdvanceState();                                                                        
3373                                                                                                          
3374         if (changed) {                                                                                   
3375         // Send an accessibility event to announce the context change                                    
3376         getWindow().getDecorView()                                                                       
3377                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3378                                                                                                          
3379         onWorkspaceShown(animated);                                                                      
3380     }                                                                                                    
3381     }                                                                                                    
3382                                                                                                          
3383     void showOverviewMode(boolean animated) {                                                            
3384         mWorkspace.setVisibility(View.VISIBLE);                                                          
3385         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,            
3386                 animated, null /* onCompleteRunnable */);                                                
3387         mState = State.WORKSPACE;                                                                        
3388         onWorkspaceShown(animated);                                                                      
3389     }                                                                                                    
3390                                                                                                          
3391     public void onWorkspaceShown(boolean animated) {                                                     
3392     }                                                                                                    
3393                                                                                                          
3394     /**                                                                                                  
3395      * Shows the apps view.                                                                              
3396      */                                                                                                  
3397     void showAppsView(boolean animated, boolean resetListToTop) {                                        
3398         if (resetListToTop) {                                                                            
3399             mAppsView.scrollToTop();                                                                     
3400         }                                                                                                
3401         showAppsOrWidgets(animated, State.APPS);                                                         
3402     }                                                                                                    
3403                                                                                                          
3404     /**                                                                                                  
3405      * Shows the widgets view.                                                                           
3406      */                                                                                                  
3407     void showWidgetsView(boolean animated, boolean resetPageToZero) {                                    
3408         Log.d(TAG, "showWidgetsView:" + animated + " resetPageToZero:" + resetPageToZero);               
3409         if (resetPageToZero) {                                                                           
3410             mWidgetsView.scrollToTop();                                                                  
3411         }                                                                                                
3412         showAppsOrWidgets(animated, State.WIDGETS);                                                      
3413                                                                                                          
3414         mWidgetsView.post(new Runnable() {                                                               
3415             @Override                                                                                    
3416             public void run() {                                                                          
3417                 mWidgetsView.requestFocus();                                                             
3418             }                                                                                            
3419         });                                                                                              
3420     }                                                                                                    
3421                                                                                                          
3422     /**                                                                                                  
3423      * Sets up the transition to show the apps/widgets view.                                             
3424      */                                                                                                  
3425     private void showAppsOrWidgets(boolean animated, State toState) {                                    
3426         if (mState != State.WORKSPACE) return;                                                           
3427         if (toState != State.APPS && toState != State.WIDGETS) return;                                   
3428                                                                                                          
3429         if (toState == State.APPS) {                                                                     
3430             mStateTransitionAnimation.startAnimationToAllApps(animated);                                 
3431             if (mLauncherCallbacks != null) {                                                            
3432                 mLauncherCallbacks.onAllAppsShown();                                                     
3433             }                                                                                            
3434         } else {                                                                                         
3435             mStateTransitionAnimation.startAnimationToWidgets(animated);                                 
3436         }                                                                                                
3437                                                                                                          
3438         // Change the state *after* we've called all the transition code                                 
3439         mState = toState;                                                                                
3440                                                                                                          
3441         // Pause the auto-advance of widgets until we are out of AllApps                                 
3442         mUserPresent = false;                                                                            
3443         updateAutoAdvanceState();                                                                        
3444         closeFolder();                                                                                   
3445                                                                                                          
3446         // Send an accessibility event to announce the context change                                    
3447         getWindow().getDecorView()                                                                       
3448                 .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                   
3449     }                                                                                                    
3450                                                                                                          
3451     public void enterSpringLoadedDragMode() {                                                            
3452         Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s",                                 
3453                 mState.name()));                                                                         
3454         if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||                           
3455                 mState == State.WIDGETS_SPRING_LOADED) {                                                 
3456             return;                                                                                      
3457         }                                                                                                
3458                                                                                                          
3459         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,       
3460                 true /* animated */, null /* onCompleteRunnable */);                                     
3461         mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;           
3462     }                                                                                                    
3463                                                                                                          
3464     public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                 
3465             final Runnable onCompleteRunnable) {                                                         
3466         if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;         
3467                                                                                                          
3468         mHandler.postDelayed(new Runnable() {                                                            
3469             @Override                                                                                    
3470             public void run() {                                                                          
3471                 if (successfulDrop) {                                                                    
3472                     // TODO(hyunyoungs): verify if this hack is still needed, if not, delete.            
3473                     //                                                                                   
3474                     // Before we show workspace, hide all apps again because                             
3475                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3476                     // clean up our state transition functions                                           
3477                     mWidgetsView.setVisibility(View.GONE);                                               
3478                     showWorkspace(true, onCompleteRunnable);                                             
3479                 } else {                                                                                 
3480                     exitSpringLoadedDragMode();                                                          
3481                 }                                                                                        
3482             }                                                                                            
3483         }, delay);                                                                                       
3484     }                                                                                                    
3485                                                                                                          
3486     void exitSpringLoadedDragMode() {                                                                    
3487         if (mState == State.APPS_SPRING_LOADED) {                                                        
3488             mStateTransitionAnimation.startAnimationToAllApps(true /* animated */);                      
3489             mState = State.APPS;                                                                         
3490         } else if (mState == State.WIDGETS_SPRING_LOADED) {                                              
3491             mStateTransitionAnimation.startAnimationToWidgets(true /* animated */);                      
3492             mState = State.WIDGETS;                                                                      
3493         }                                                                                                
3494         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3495     }                                                                                                    
3496                                                                                                          
3497     void lockAllApps() {                                                                                 
3498         // TODO                                                                                          
3499     }                                                                                                    
3500                                                                                                          
3501     void unlockAllApps() {                                                                               
3502         // TODO                                                                                          
3503     }                                                                                                    
3504                                                                                                          
3505     protected void disableVoiceButtonProxy(boolean disable) {                                            
3506         // NO-OP                                                                                         
3507     }                                                                                                    
3508                                                                                                          
3509     public View getOrCreateQsbBar() {                                                                    
3510         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
3511             return mLauncherCallbacks.getQsbBar();                                                       
3512         }                                                                                                
3513                                                                                                          
3514         if (mQsb == null) {                                                                              
3515             AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);              
3516             if (searchProvider == null) {                                                                
3517                 return null;                                                                             
3518             }                                                                                            
3519                                                                                                          
3520             Bundle opts = new Bundle();                                                                  
3521             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                 
3522                     AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                    
3523                                                                                                          
3524             SharedPreferences sp = getSharedPreferences(                                                 
3525                     LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                           
3526             int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                 
3527             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);             
3528             if (!searchProvider.provider.flattenToString().equals(                                       
3529                     sp.getString(QSB_WIDGET_PROVIDER, null))                                             
3530                     || (widgetInfo == null)                                                              
3531                     || !widgetInfo.provider.equals(searchProvider.provider)) {                           
3532                 // A valid widget is not already bound.                                                  
3533                 if (widgetId > -1) {                                                                     
3534                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3535                     widgetId = -1;                                                                       
3536                 }                                                                                        
3537                                                                                                          
3538                 // Try to bind a new widget                                                              
3539                 widgetId = mAppWidgetHost.allocateAppWidgetId();                                         
3540                                                                                                          
3541                 if (!AppWidgetManagerCompat.getInstance(this)                                            
3542                         .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                     
3543                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3544                     widgetId = -1;                                                                       
3545                 }                                                                                        
3546                                                                                                          
3547                 sp.edit()                                                                                
3548                     .putInt(QSB_WIDGET_ID, widgetId)                                                     
3549                     .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())           
3550                     .commit();                                                                           
3551             }                                                                                            
3552                                                                                                          
3553             if (widgetId != -1) {                                                                        
3554                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                        
3555                 mQsb.updateAppWidgetOptions(opts);                                                       
3556                 mQsb.setPadding(0, 0, 0, 0);                                                             
3557                 mSearchDropTargetBar.addView(mQsb);                                                      
3558                 mSearchDropTargetBar.setQsbSearchBar(mQsb);                                              
3559             }                                                                                            
3560         }                                                                                                
3561         return mQsb;                                                                                     
3562     }                                                                                                    
3563                                                                                                          
3564     private void reinflateQSBIfNecessary() {                                                             
3565         if (mQsb instanceof LauncherAppWidgetHostView &&                                                 
3566                 ((LauncherAppWidgetHostView) mQsb).isReinflateRequired()) {                              
3567             mSearchDropTargetBar.removeView(mQsb);                                                       
3568             mQsb = null;                                                                                 
3569             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
3570         }                                                                                                
3571     }                                                                                                    
3572                                                                                                          
3573     @Override                                                                                            
3574     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3575         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3576         final List<CharSequence> text = event.getText();                                                 
3577         text.clear();                                                                                    
3578         // Populate event with a fake title based on the current state.                                  
3579         if (mState == State.APPS) {                                                                      
3580             text.add("Apps");                                                                            
3581         } else if (mState == State.WIDGETS) {                                                            
3582             text.add("Widgets");                                                                         
3583         } else {                                                                                         
3584             text.add(getString(R.string.all_apps_home_button_label));                                    
3585         }                                                                                                
3586         return result;                                                                                   
3587     }                                                                                                    
3588                                                                                                          
3589     /**                                                                                                  
3590      * Receives notifications when system dialogs are to be closed.                                      
3591      */                                                                                                  
3592     @Thunk class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                            
3593         @Override                                                                                        
3594         public void onReceive(Context context, Intent intent) {                                          
3595             closeSystemDialogs();                                                                        
3596         }                                                                                                
3597     }                                                                                                    
3598                                                                                                          
3599     /**                                                                                                  
3600      * Receives notifications whenever the appwidgets are reset.                                         
3601      */                                                                                                  
3602     private class AppWidgetResetObserver extends ContentObserver {                                       
3603         public AppWidgetResetObserver() {                                                                
3604             super(new Handler());                                                                        
3605         }                                                                                                
3606                                                                                                          
3607         @Override                                                                                        
3608         public void onChange(boolean selfChange) {                                                       
3609             onAppWidgetReset();                                                                          
3610         }                                                                                                
3611     }                                                                                                    
3612                                                                                                          
3613     /**                                                                                                  
3614      * If the activity is currently paused, signal that we need to run the passed Runnable               
3615      * in onResume.                                                                                      
3616      *                                                                                                   
3617      * This needs to be called from incoming places where resources might have been loaded               
3618      * while we are paused.  That is becaues the Configuration might be wrong                            
3619      * when we're not running, and if it comes back to what it was when we                               
3620      * were paused, we are not restarted.                                                                
3621      *                                                                                                   
3622      * Implementation of the method from LauncherModel.Callbacks.                                        
3623      *                                                                                                   
3624      * @return true if we are currently paused.  The caller might be able to                             
3625      * skip some work in that case since we will come back again.                                        
3626      */                                                                                                  
3627     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3628         if (mPaused) {                                                                                   
3629             Log.i(TAG, "Deferring update until onResume");                                               
3630             if (deletePreviousRunnables) {                                                               
3631                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3632                 }                                                                                        
3633             }                                                                                            
3634             mBindOnResumeCallbacks.add(run);                                                             
3635             return true;                                                                                 
3636         } else {                                                                                         
3637             return false;                                                                                
3638         }                                                                                                
3639     }                                                                                                    
3640                                                                                                          
3641     private boolean waitUntilResume(Runnable run) {                                                      
3642         return waitUntilResume(run, false);                                                              
3643     }                                                                                                    
3644                                                                                                          
3645     public void addOnResumeCallback(Runnable run) {                                                      
3646         mOnResumeCallbacks.add(run);                                                                     
3647     }                                                                                                    
3648                                                                                                          
3649     /**                                                                                                  
3650      * If the activity is currently paused, signal that we need to re-run the loader                     
3651      * in onResume.                                                                                      
3652      *                                                                                                   
3653      * This needs to be called from incoming places where resources might have been loaded               
3654      * while we are paused.  That is becaues the Configuration might be wrong                            
3655      * when we're not running, and if it comes back to what it was when we                               
3656      * were paused, we are not restarted.                                                                
3657      *                                                                                                   
3658      * Implementation of the method from LauncherModel.Callbacks.                                        
3659      *                                                                                                   
3660      * @return true if we are currently paused.  The caller might be able to                             
3661      * skip some work in that case since we will come back again.                                        
3662      */                                                                                                  
3663     public boolean setLoadOnResume() {                                                                   
3664         if (mPaused) {                                                                                   
3665             Log.i(TAG, "setLoadOnResume");                                                               
3666             mOnResumeNeedsLoad = true;                                                                   
3667             return true;                                                                                 
3668         } else {                                                                                         
3669             return false;                                                                                
3670         }                                                                                                
3671     }                                                                                                    
3672                                                                                                          
3673     /**                                                                                                  
3674      * Implementation of the method from LauncherModel.Callbacks.                                        
3675      */                                                                                                  
3676     public int getCurrentWorkspaceScreen() {                                                             
3677         if (mWorkspace != null) {                                                                        
3678             return mWorkspace.getCurrentPage();                                                          
3679         } else {                                                                                         
3680             return SCREEN_COUNT / 2;                                                                     
3681         }                                                                                                
3682     }                                                                                                    
3683                                                                                                          
3684     /**                                                                                                  
3685      * Refreshes the shortcuts shown on the workspace.                                                   
3686      *                                                                                                   
3687      * Implementation of the method from LauncherModel.Callbacks.                                        
3688      */                                                                                                  
3689     public void startBinding() {                                                                         
3690         setWorkspaceLoading(true);                                                                       
3691                                                                                                          
3692         // If we're starting binding all over again, clear any bind calls we'd postponed in              
3693         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
3694         // from scratch again                                                                            
3695         mBindOnResumeCallbacks.clear();                                                                  
3696                                                                                                          
3697         // Clear the workspace because it's going to be rebound                                          
3698         mWorkspace.clearDropTargets();                                                                   
3699         mWorkspace.removeAllWorkspaceScreens();                                                          
3700                                                                                                          
3701         mWidgetsToAdvance.clear();                                                                       
3702         if (mHotseat != null) {                                                                          
3703             mHotseat.resetLayout();                                                                      
3704         }                                                                                                
3705     }                                                                                                    
3706                                                                                                          
3707     @Override                                                                                            
3708     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
3709         bindAddScreens(orderedScreenIds);                                                                
3710                                                                                                          
3711         // If there are no screens, we need to have an empty screen                                      
3712         if (orderedScreenIds.size() == 0) {                                                              
3713             mWorkspace.addExtraEmptyScreen();                                                            
3714         }                                                                                                
3715                                                                                                          
3716         // Create the custom content page (this call updates mDefaultScreen which calls                  
3717         // setCurrentPage() so ensure that all pages are added before calling this).                     
3718         if (hasCustomContentToLeft()) {                                                                  
3719             mWorkspace.createCustomContentContainer();                                                   
3720             populateCustomContentContainer();                                                            
3721         }                                                                                                
3722     }                                                                                                    
3723                                                                                                          
3724     @Override                                                                                            
3725     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
3726         // Log to disk                                                                                   
3727         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
3728         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
3729                 TextUtils.join(", ", orderedScreenIds), true);                                           
3730         int count = orderedScreenIds.size();                                                             
3731         for (int i = 0; i < count; i++) {                                                                
3732             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
3733         }                                                                                                
3734     }                                                                                                    
3735                                                                                                          
3736     @Override                                                                                            
3737     public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                  
3738             final long screenId, final int[] cell, final int spanX, final int spanY) {                   
3739         showWorkspace(true, new Runnable() {                                                             
3740                                                                                                          
3741             @Override                                                                                    
3742             public void run() {                                                                          
3743                 mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                     
3744                 addPendingItem(info, container, screenId, cell, spanX, spanY);                           
3745             }                                                                                            
3746         });                                                                                              
3747     }                                                                                                    
3748                                                                                                          
3749     private boolean shouldShowWeightWatcher() {                                                          
3750         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3751         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3752         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
3753                                                                                                          
3754         return show;                                                                                     
3755     }                                                                                                    
3756                                                                                                          
3757     private void toggleShowWeightWatcher() {                                                             
3758         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3759         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3760         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
3761                                                                                                          
3762         show = !show;                                                                                    
3763                                                                                                          
3764         SharedPreferences.Editor editor = sp.edit();                                                     
3765         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
3766         editor.commit();                                                                                 
3767                                                                                                          
3768         if (mWeightWatcher != null) {                                                                    
3769             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
3770         }                                                                                                
3771     }                                                                                                    
3772                                                                                                          
3773     public void bindAppsAdded(final ArrayList<Long> newScreens,                                          
3774                               final ArrayList<ItemInfo> addNotAnimated,                                  
3775                               final ArrayList<ItemInfo> addAnimated,                                     
3776                               final ArrayList<AppInfo> addedApps) {                                      
3777         Runnable r = new Runnable() {                                                                    
3778             public void run() {                                                                          
3779                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
3780             }                                                                                            
3781         };                                                                                               
3782         if (waitUntilResume(r)) {                                                                        
3783             return;                                                                                      
3784         }                                                                                                
3785                                                                                                          
3786         // Add the new screens                                                                           
3787         if (newScreens != null) {                                                                        
3788             bindAddScreens(newScreens);                                                                  
3789         }                                                                                                
3790                                                                                                          
3791         // We add the items without animation on non-visible pages, and with                             
3792         // animations on the new page (which we will try and snap to).                                   
3793         if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                       
3794             bindItems(addNotAnimated, 0,                                                                 
3795                     addNotAnimated.size(), false);                                                       
3796         }                                                                                                
3797         if (addAnimated != null && !addAnimated.isEmpty()) {                                             
3798             bindItems(addAnimated, 0,                                                                    
3799                     addAnimated.size(), true);                                                           
3800         }                                                                                                
3801                                                                                                          
3802         // Remove the extra empty screen                                                                 
3803         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
3804                                                                                                          
3805         if (addedApps != null && mAppsView != null) {                                                    
3806             mAppsView.addApps(addedApps);                                                                
3807         }                                                                                                
3808     }                                                                                                    
3809                                                                                                          
3810     /**                                                                                                  
3811      * Bind the items start-end from the list.                                                           
3812      *                                                                                                   
3813      * Implementation of the method from LauncherModel.Callbacks.                                        
3814      */                                                                                                  
3815     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
3816                           final boolean forceAnimateIcons) {                                             
3817         Runnable r = new Runnable() {                                                                    
3818             public void run() {                                                                          
3819                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
3820             }                                                                                            
3821         };                                                                                               
3822         if (waitUntilResume(r)) {                                                                        
3823             return;                                                                                      
3824         }                                                                                                
3825                                                                                                          
3826         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
3827         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
3828         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
3829         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
3830         Workspace workspace = mWorkspace;                                                                
3831         long newShortcutsScreenId = -1;                                                                  
3832         for (int i = start; i < end; i++) {                                                              
3833             final ItemInfo item = shortcuts.get(i);                                                      
3834                                                                                                          
3835             // Short circuit if we are loading dock items for a configuration which has no dock          
3836             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
3837                     mHotseat == null) {                                                                  
3838                 continue;                                                                                
3839             }                                                                                            
3840                                                                                                          
3841             switch (item.itemType) {                                                                     
3842                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
3843                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
3844                     ShortcutInfo info = (ShortcutInfo) item;                                             
3845                     View shortcut = createShortcut(info);                                                
3846                                                                                                          
3847                     /*                                                                                   
3848                      * TODO: FIX collision case                                                          
3849                      */                                                                                  
3850                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
3851                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
3852                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
3853                             View v = cl.getChildAt(item.cellX, item.cellY);                              
3854                             Object tag = v.getTag();                                                     
3855                             String desc = "Collision while binding workspace item: " + item              
3856                                     + ". Collides with " + tag;                                          
3857                             if (LauncherAppState.isDogfoodBuild()) {                                     
3858                                 throw (new RuntimeException(desc));                                      
3859                             } else {                                                                     
3860                                 Log.d(TAG, desc);                                                        
3861                             }                                                                            
3862                         }                                                                                
3863                     }                                                                                    
3864                                                                                                          
3865                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
3866                             item.cellY, 1, 1);                                                           
3867                     if (animateIcons) {                                                                  
3868                         // Animate all the applications up now                                           
3869                         shortcut.setAlpha(0f);                                                           
3870                         shortcut.setScaleX(0f);                                                          
3871                         shortcut.setScaleY(0f);                                                          
3872                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
3873                         newShortcutsScreenId = item.screenId;                                            
3874                     }                                                                                    
3875                     break;                                                                               
3876                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
3877                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
3878                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
3879                             (FolderInfo) item, mIconCache);                                              
3880                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
3881                             item.cellY, 1, 1);                                                           
3882                     break;                                                                               
3883                 default:                                                                                 
3884                     throw new RuntimeException("Invalid Item Type");                                     
3885             }                                                                                            
3886         }                                                                                                
3887                                                                                                          
3888         if (animateIcons) {                                                                              
3889             // Animate to the correct page                                                               
3890             if (newShortcutsScreenId > -1) {                                                             
3891                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
3892                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
3893                 final Runnable startBounceAnimRunnable = new Runnable() {                                
3894                     public void run() {                                                                  
3895                         anim.playTogether(bounceAnims);                                                  
3896                         anim.start();                                                                    
3897                     }                                                                                    
3898                 };                                                                                       
3899                 if (newShortcutsScreenId != currentScreenId) {                                           
3900                     // We post the animation slightly delayed to prevent slowdowns                       
3901                     // when we are loading right after we return to launcher.                            
3902                     mWorkspace.postDelayed(new Runnable() {                                              
3903                         public void run() {                                                              
3904                             if (mWorkspace != null) {                                                    
3905                                 mWorkspace.snapToPage(newScreenIndex);                                   
3906                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
3907                                         NEW_APPS_ANIMATION_DELAY);                                       
3908                             }                                                                            
3909                         }                                                                                
3910                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
3911                 } else {                                                                                 
3912                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
3913                 }                                                                                        
3914             }                                                                                            
3915         }                                                                                                
3916         workspace.requestLayout();                                                                       
3917     }                                                                                                    
3918                                                                                                          
3919     /**                                                                                                  
3920      * Implementation of the method from LauncherModel.Callbacks.                                        
3921      */                                                                                                  
3922     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
3923         Runnable r = new Runnable() {                                                                    
3924             public void run() {                                                                          
3925                 bindFolders(folders);                                                                    
3926             }                                                                                            
3927         };                                                                                               
3928         if (waitUntilResume(r)) {                                                                        
3929             return;                                                                                      
3930         }                                                                                                
3931         sFolders.clear();                                                                                
3932         sFolders.putAll(folders);                                                                        
3933     }                                                                                                    
3934                                                                                                          
3935     /**                                                                                                  
3936      * Add the views for a widget to the workspace.                                                      
3937      *                                                                                                   
3938      * Implementation of the method from LauncherModel.Callbacks.                                        
3939      */                                                                                                  
3940     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
3941         Runnable r = new Runnable() {                                                                    
3942             public void run() {                                                                          
3943                 bindAppWidget(item);                                                                     
3944             }                                                                                            
3945         };                                                                                               
3946         if (waitUntilResume(r)) {                                                                        
3947             return;                                                                                      
3948         }                                                                                                
3949                                                                                                          
3950         final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                               
3951         if (DEBUG_WIDGETS) {                                                                             
3952             Log.d(TAG, "bindAppWidget: " + item);                                                        
3953         }                                                                                                
3954         final Workspace workspace = mWorkspace;                                                          
3955                                                                                                          
3956         LauncherAppWidgetProviderInfo appWidgetInfo =                                                    
3957                 LauncherModel.getProviderInfo(this, item.providerName, item.user);                       
3958                                                                                                          
3959         if (!mIsSafeModeEnabled                                                                          
3960                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)           
3961                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {              
3962             if (appWidgetInfo == null) {                                                                 
3963                 if (DEBUG_WIDGETS) {                                                                     
3964                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3965                             + " belongs to component " + item.providerName                               
3966                             + ", as the povider is null");                                               
3967                 }                                                                                        
3968                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3969                 return;                                                                                  
3970             }                                                                                            
3971             // Note: This assumes that the id remap broadcast is received before this step.              
3972             // If that is not the case, the id remap will be ignored and user may see the                
3973             // click to setup view.                                                                      
3974             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);            
3975             pendingInfo.spanX = item.spanX;                                                              
3976             pendingInfo.spanY = item.spanY;                                                              
3977             pendingInfo.minSpanX = item.minSpanX;                                                        
3978             pendingInfo.minSpanY = item.minSpanY;                                                        
3979             Bundle options = null;                                                                       
3980             //        AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);              
3981                                                                                                          
3982             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
3983             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                
3984                     newWidgetId, appWidgetInfo, options);                                                
3985                                                                                                          
3986             // TODO consider showing a permission dialog when the widget is clicked.                     
3987             if (!success) {                                                                              
3988                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
3989                 if (DEBUG_WIDGETS) {                                                                     
3990                     Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                        
3991                             + " belongs to component " + item.providerName                               
3992                             + ", as the launcher is unable to bing a new widget id");                    
3993                 }                                                                                        
3994                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3995                 return;                                                                                  
3996             }                                                                                            
3997                                                                                                          
3998             item.appWidgetId = newWidgetId;                                                              
3999                                                                                                          
4000             // If the widget has a configure activity, it is still needs to set it up, otherwise         
4001             // the widget is ready to go.                                                                
4002             item.restoreStatus = (appWidgetInfo.configure == null)                                       
4003                     ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                            
4004                     : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                           
4005                                                                                                          
4006             LauncherModel.updateItemInDatabase(this, item);                                              
4007         }                                                                                                
4008                                                                                                          
4009         if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {      
4010             final int appWidgetId = item.appWidgetId;                                                    
4011             if (DEBUG_WIDGETS) {                                                                         
4012                 Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "            
4013                         + appWidgetInfo.provider);                                                       
4014             }                                                                                            
4015                                                                                                          
4016             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
4017         } else {                                                                                         
4018             appWidgetInfo = null;                                                                        
4019             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                     
4020                     mIsSafeModeEnabled);                                                                 
4021             view.updateIcon(mIconCache);                                                                 
4022             item.hostView = view;                                                                        
4023             item.hostView.updateAppWidget(null);                                                         
4024             item.hostView.setOnClickListener(this);                                                      
4025         }                                                                                                
4026                                                                                                          
4027         item.hostView.setTag(item);                                                                      
4028         item.onBindAppWidget(this);                                                                      
4029                                                                                                          
4030         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                  
4031                 item.cellY, item.spanX, item.spanY, false);                                              
4032         if (!item.isCustomWidget()) {                                                                    
4033             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
4034         }                                                                                                
4035                                                                                                          
4036         workspace.requestLayout();                                                                       
4037                                                                                                          
4038         if (DEBUG_WIDGETS) {                                                                             
4039             Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                        
4040                     + (SystemClock.uptimeMillis()-start) + "ms");                                        
4041         }                                                                                                
4042     }                                                                                                    
4043                                                                                                          
4044     /**                                                                                                  
4045      * Restores a pending widget.                                                                        
4046      *                                                                                                   
4047      * @param appWidgetId The app widget id                                                              
4048      * @param cellInfo The position on screen where to create the widget.                                
4049      */                                                                                                  
4050     private void completeRestoreAppWidget(final int appWidgetId) {                                       
4051         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
4052         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
4053             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
4054             return;                                                                                      
4055         }                                                                                                
4056                                                                                                          
4057         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
4058         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
4059                                                                                                          
4060         mWorkspace.reinflateWidgetsIfNecessary();                                                        
4061         LauncherModel.updateItemInDatabase(this, info);                                                  
4062     }                                                                                                    
4063                                                                                                          
4064     public void onPageBoundSynchronously(int page) {                                                     
4065         mSynchronouslyBoundPages.add(page);                                                              
4066     }                                                                                                    
4067                                                                                                          
4068     /**                                                                                                  
4069      * Callback saying that there aren't any more items to bind.                                         
4070      *                                                                                                   
4071      * Implementation of the method from LauncherModel.Callbacks.                                        
4072      */                                                                                                  
4073     public void finishBindingItems() {                                                                   
4074         Runnable r = new Runnable() {                                                                    
4075             public void run() {                                                                          
4076                 finishBindingItems();                                                                    
4077             }                                                                                            
4078         };                                                                                               
4079         if (waitUntilResume(r)) {                                                                        
4080             return;                                                                                      
4081         }                                                                                                
4082         if (mSavedState != null) {                                                                       
4083             if (!mWorkspace.hasFocus()) {                                                                
4084                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
4085             }                                                                                            
4086             mSavedState = null;                                                                          
4087         }                                                                                                
4088                                                                                                          
4089         mWorkspace.restoreInstanceStateForRemainingPages();                                              
4090                                                                                                          
4091         setWorkspaceLoading(false);                                                                      
4092         sendLoadingCompleteBroadcastIfNecessary();                                                       
4093                                                                                                          
4094         // If we received the result of any pending adds while the loader was running (e.g. the          
4095         // widget configuration forced an orientation change), process them now.                         
4096         if (sPendingAddItem != null) {                                                                   
4097             final long screenId = completeAdd(sPendingAddItem);                                          
4098                                                                                                          
4099             // TODO: this moves the user to the page where the pending item was added. Ideally,          
4100             // the screen would be guaranteed to exist after bind, and the page would be set through     
4101             // the workspace restore process.                                                            
4102             mWorkspace.post(new Runnable() {                                                             
4103                 @Override                                                                                
4104                 public void run() {                                                                      
4105                     mWorkspace.snapToScreenId(screenId);                                                 
4106                 }                                                                                        
4107             });                                                                                          
4108             sPendingAddItem = null;                                                                      
4109         }                                                                                                
4110                                                                                                          
4111         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
4112                                                                                                          
4113         if (mLauncherCallbacks != null) {                                                                
4114             mLauncherCallbacks.finishBindingItems(false);                                                
4115         }                                                                                                
4116     }                                                                                                    
4117                                                                                                          
4118     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
4119         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
4120             String permission =                                                                          
4121                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
4122             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
4123             sendBroadcast(intent, permission);                                                           
4124             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
4125             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
4126             editor.apply();                                                                              
4127         }                                                                                                
4128     }                                                                                                    
4129                                                                                                          
4130     public boolean isAllAppsButtonRank(int rank) {                                                       
4131         if (mHotseat != null) {                                                                          
4132             return mHotseat.isAllAppsButtonRank(rank);                                                   
4133         }                                                                                                
4134         return false;                                                                                    
4135     }                                                                                                    
4136                                                                                                          
4137     private boolean canRunNewAppsAnimation() {                                                           
4138         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
4139         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
4140     }                                                                                                    
4141                                                                                                          
4142     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
4143         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
4144                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
4145                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
4146                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
4147         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
4148         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
4149         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
4150         return bounceAnim;                                                                               
4151     }                                                                                                    
4152                                                                                                          
4153     public boolean useVerticalBarLayout() {                                                              
4154         return LauncherAppState.getInstance().getDynamicGrid().                                          
4155                 getDeviceProfile().isVerticalBarLayout();                                                
4156     }                                                                                                    
4157                                                                                                          
4158     protected Rect getSearchBarBounds() {                                                                
4159         return LauncherAppState.getInstance().getDynamicGrid().                                          
4160                 getDeviceProfile().getSearchBarBounds();                                                 
4161     }                                                                                                    
4162                                                                                                          
4163     public void bindSearchablesChanged() {                                                               
4164         if (mSearchDropTargetBar == null) {                                                              
4165             return;                                                                                      
4166         }                                                                                                
4167         if (mQsb != null) {                                                                              
4168             mSearchDropTargetBar.removeView(mQsb);                                                       
4169             mQsb = null;                                                                                 
4170         }                                                                                                
4171         mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                       
4172     }                                                                                                    
4173                                                                                                          
4174     /**                                                                                                  
4175      * Add the icons for all apps.                                                                       
4176      *                                                                                                   
4177      * Implementation of the method from LauncherModel.Callbacks.                                        
4178      */                                                                                                  
4179     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4180         if (mAppsView != null) {                                                                         
4181             mAppsView.setApps(apps);                                                                     
4182                 }                                                                                        
4183         if (mWidgetsView != null) {                                                                      
4184             mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),             
4185                     getPackageManager());                                                                
4186         }                                                                                                
4187         if (mLauncherCallbacks != null) {                                                                
4188             mLauncherCallbacks.bindAllApplications(apps);                                                
4189         }                                                                                                
4190     }                                                                                                    
4191                                                                                                          
4192     /**                                                                                                  
4193      * A package was updated.                                                                            
4194      *                                                                                                   
4195      * Implementation of the method from LauncherModel.Callbacks.                                        
4196      */                                                                                                  
4197     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4198         Runnable r = new Runnable() {                                                                    
4199             public void run() {                                                                          
4200                 bindAppsUpdated(apps);                                                                   
4201             }                                                                                            
4202         };                                                                                               
4203         if (waitUntilResume(r)) {                                                                        
4204             return;                                                                                      
4205         }                                                                                                
4206                                                                                                          
4207         if (mAppsView != null) {                                                                         
4208             mAppsView.updateApps(apps);                                                                  
4209         }                                                                                                
4210     }                                                                                                    
4211                                                                                                          
4212     @Override                                                                                            
4213     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                    
4214         Runnable r = new Runnable() {                                                                    
4215             public void run() {                                                                          
4216                 bindWidgetsRestored(widgets);                                                            
4217             }                                                                                            
4218         };                                                                                               
4219         if (waitUntilResume(r)) {                                                                        
4220             return;                                                                                      
4221         }                                                                                                
4222         mWorkspace.widgetsRestored(widgets);                                                             
4223     }                                                                                                    
4224                                                                                                          
4225     /**                                                                                                  
4226      * Some shortcuts were updated in the background.                                                    
4227      *                                                                                                   
4228      * Implementation of the method from LauncherModel.Callbacks.                                        
4229      */                                                                                                  
4230     @Override                                                                                            
4231     public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                              
4232             final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                        
4233         Runnable r = new Runnable() {                                                                    
4234             public void run() {                                                                          
4235                 bindShortcutsChanged(updated, removed, user);                                            
4236             }                                                                                            
4237         };                                                                                               
4238         if (waitUntilResume(r)) {                                                                        
4239             return;                                                                                      
4240         }                                                                                                
4241                                                                                                          
4242         if (!updated.isEmpty()) {                                                                        
4243             mWorkspace.updateShortcuts(updated);                                                         
4244         }                                                                                                
4245                                                                                                          
4246         if (!removed.isEmpty()) {                                                                        
4247             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4248             for (ShortcutInfo si : removed) {                                                            
4249                 removedComponents.add(si.getTargetComponent());                                          
4250             }                                                                                            
4251             mWorkspace.removeItemsByComponentName(removedComponents, user);                              
4252             // Notify the drag controller                                                                
4253             mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                   
4254         }                                                                                                
4255     }                                                                                                    
4256                                                                                                          
4257     /**                                                                                                  
4258      * Update the state of a package, typically related to install state.                                
4259      *                                                                                                   
4260      * Implementation of the method from LauncherModel.Callbacks.                                        
4261      */                                                                                                  
4262     @Override                                                                                            
4263     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4264         if (mWorkspace != null) {                                                                        
4265             mWorkspace.updatePackageState(installInfo);                                                  
4266         }                                                                                                
4267     }                                                                                                    
4268                                                                                                          
4269     /**                                                                                                  
4270      * Update the label and icon of all the icons in a package                                           
4271      *                                                                                                   
4272      * Implementation of the method from LauncherModel.Callbacks.                                        
4273      */                                                                                                  
4274     @Override                                                                                            
4275     public void updatePackageBadge(String packageName) {                                                 
4276         if (mWorkspace != null) {                                                                        
4277             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4278         }                                                                                                
4279     }                                                                                                    
4280                                                                                                          
4281     /**                                                                                                  
4282      * A package was uninstalled.  We take both the super set of packageNames                            
4283      * in addition to specific applications to remove, the reason being that                             
4284      * this can be called when a package is updated as well.  In that scenario,                          
4285      * we only remove specific components from the workspace, where as                                   
4286      * package-removal should clear all items by package name.                                           
4287      *                                                                                                   
4288      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4289      * Implementation of the method from LauncherModel.Callbacks.                                        
4290      */                                                                                                  
4291     @Override                                                                                            
4292     public void bindComponentsRemoved(final ArrayList<String> packageNames,                              
4293             final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {          
4294         Runnable r = new Runnable() {                                                                    
4295             public void run() {                                                                          
4296                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4297             }                                                                                            
4298         };                                                                                               
4299         if (waitUntilResume(r)) {                                                                        
4300             return;                                                                                      
4301         }                                                                                                
4302                                                                                                          
4303         if (reason == 0) {                                                                               
4304             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4305             for (AppInfo info : appInfos) {                                                              
4306                 removedComponents.add(info.componentName);                                               
4307             }                                                                                            
4308             if (!packageNames.isEmpty()) {                                                               
4309                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4310             }                                                                                            
4311             if (!removedComponents.isEmpty()) {                                                          
4312                 mWorkspace.removeItemsByComponentName(removedComponents, user);                          
4313             }                                                                                            
4314             // Notify the drag controller                                                                
4315             mDragController.onAppsRemoved(packageNames, removedComponents);                              
4316                                                                                                          
4317         } else {                                                                                         
4318             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4319         }                                                                                                
4320                                                                                                          
4321         // Update AllApps                                                                                
4322         if (mAppsView != null) {                                                                         
4323             mAppsView.removeApps(appInfos);                                                              
4324         }                                                                                                
4325     }                                                                                                    
4326                                                                                                          
4327     /**                                                                                                  
4328      * A number of packages were updated.                                                                
4329      */                                                                                                  
4330     @Thunk ArrayList<Object> mWidgetsAndShortcuts;                                                       
4331     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4332             public void run() {                                                                          
4333                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4334                 mWidgetsAndShortcuts = null;                                                             
4335             }                                                                                            
4336         };                                                                                               
4337                                                                                                          
4338     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4339         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4340             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4341             return;                                                                                      
4342         }                                                                                                
4343                                                                                                          
4344         if (mWidgetsView != null) {                                                                      
4345             mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),             
4346                     getPackageManager());                                                                
4347         }                                                                                                
4348     }                                                                                                    
4349                                                                                                          
4350     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4351         final Display d = getWindowManager().getDefaultDisplay();                                        
4352         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4353         switch (d.getRotation()) {                                                                       
4354         case Surface.ROTATION_0:                                                                         
4355         case Surface.ROTATION_180:                                                                       
4356             // We are currently in the same basic orientation as the natural orientation                 
4357             naturalOri = configOri;                                                                      
4358             break;                                                                                       
4359         case Surface.ROTATION_90:                                                                        
4360         case Surface.ROTATION_270:                                                                       
4361             // We are currently in the other basic orientation to the natural orientation                
4362             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4363                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4364             break;                                                                                       
4365         }                                                                                                
4366                                                                                                          
4367         int[] oriMap = {                                                                                 
4368                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4369                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4370                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4371                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4372         };                                                                                               
4373         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4374         // is landscape.                                                                                 
4375         int indexOffset = 0;                                                                             
4376         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4377             indexOffset = 1;                                                                             
4378         }                                                                                                
4379         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4380     }                                                                                                    
4381                                                                                                          
4382     public void lockScreenOrientation() {                                                                
4383         if (Utilities.isRotationEnabled(this)) {                                                         
4384             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                            
4385                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                
4386                         .getConfiguration().orientation));                                               
4387             } else {                                                                                     
4388                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                         
4389             }                                                                                            
4390         }                                                                                                
4391     }                                                                                                    
4392     public void unlockScreenOrientation(boolean immediate) {                                             
4393         if (Utilities.isRotationEnabled(this)) {                                                         
4394             if (immediate) {                                                                             
4395                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4396             } else {                                                                                     
4397                 mHandler.postDelayed(new Runnable() {                                                    
4398                     public void run() {                                                                  
4399                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4400                     }                                                                                    
4401                 }, mRestoreScreenOrientationDelay);                                                      
4402             }                                                                                            
4403         }                                                                                                
4404     }                                                                                                    
4405                                                                                                          
4406     protected boolean isLauncherPreinstalled() {                                                         
4407         if (mLauncherCallbacks != null) {                                                                
4408             return mLauncherCallbacks.isLauncherPreinstalled();                                          
4409         }                                                                                                
4410         PackageManager pm = getPackageManager();                                                         
4411         try {                                                                                            
4412             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4413             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4414                 return true;                                                                             
4415             } else {                                                                                     
4416                 return false;                                                                            
4417             }                                                                                            
4418         } catch (NameNotFoundException e) {                                                              
4419             e.printStackTrace();                                                                         
4420             return false;                                                                                
4421         }                                                                                                
4422     }                                                                                                    
4423                                                                                                          
4424     /**                                                                                                  
4425      * This method indicates whether or not we should suggest default wallpaper dimensions               
4426      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4427      */                                                                                                  
4428     protected boolean overrideWallpaperDimensions() {                                                    
4429         if (mLauncherCallbacks != null) {                                                                
4430             return mLauncherCallbacks.overrideWallpaperDimensions();                                     
4431         }                                                                                                
4432         return true;                                                                                     
4433     }                                                                                                    
4434                                                                                                          
4435     /**                                                                                                  
4436      * To be overridden by subclasses to indicate that there is an activity to launch                    
4437      * before showing the standard launcher experience.                                                  
4438      */                                                                                                  
4439     protected boolean hasFirstRunActivity() {                                                            
4440         if (mLauncherCallbacks != null) {                                                                
4441             return mLauncherCallbacks.hasFirstRunActivity();                                             
4442         }                                                                                                
4443         return false;                                                                                    
4444     }                                                                                                    
4445                                                                                                          
4446     /**                                                                                                  
4447      * To be overridden by subclasses to launch any first run activity                                   
4448      */                                                                                                  
4449     protected Intent getFirstRunActivity() {                                                             
4450         if (mLauncherCallbacks != null) {                                                                
4451             return mLauncherCallbacks.getFirstRunActivity();                                             
4452         }                                                                                                
4453         return null;                                                                                     
4454     }                                                                                                    
4455                                                                                                          
4456     /**                                                                                                  
4457      * Returns whether the launcher callbacks overrides search in all apps.                              
4458      * @return                                                                                           
4459      */                                                                                                  
4460     @Thunk boolean isAllAppsSearchOverridden() {                                                         
4461         if (mLauncherCallbacks != null) {                                                                
4462             return mLauncherCallbacks.overrideAllAppsSearch();                                           
4463         }                                                                                                
4464         return false;                                                                                    
4465     }                                                                                                    
4466                                                                                                          
4467     private boolean shouldRunFirstRunActivity() {                                                        
4468         return !ActivityManager.isRunningInTestHarness() &&                                              
4469                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4470     }                                                                                                    
4471                                                                                                          
4472     protected boolean hasRunFirstRunActivity() {                                                         
4473         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4474     }                                                                                                    
4475                                                                                                          
4476     public boolean showFirstRunActivity() {                                                              
4477         if (shouldRunFirstRunActivity() &&                                                               
4478                 hasFirstRunActivity()) {                                                                 
4479             Intent firstRunIntent = getFirstRunActivity();                                               
4480             if (firstRunIntent != null) {                                                                
4481                 startActivity(firstRunIntent);                                                           
4482                 markFirstRunActivityShown();                                                             
4483                 return true;                                                                             
4484             }                                                                                            
4485         }                                                                                                
4486         return false;                                                                                    
4487     }                                                                                                    
4488                                                                                                          
4489     private void markFirstRunActivityShown() {                                                           
4490         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4491         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4492         editor.apply();                                                                                  
4493     }                                                                                                    
4494                                                                                                          
4495     /**                                                                                                  
4496      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4497      * screen that must be displayed and dismissed.                                                      
4498      */                                                                                                  
4499     protected boolean hasDismissableIntroScreen() {                                                      
4500         if (mLauncherCallbacks != null) {                                                                
4501             return mLauncherCallbacks.hasDismissableIntroScreen();                                       
4502         }                                                                                                
4503         return false;                                                                                    
4504     }                                                                                                    
4505                                                                                                          
4506     /**                                                                                                  
4507      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4508      */                                                                                                  
4509     protected View getIntroScreen() {                                                                    
4510         if (mLauncherCallbacks != null) {                                                                
4511             return mLauncherCallbacks.getIntroScreen();                                                  
4512         }                                                                                                
4513         return null;                                                                                     
4514     }                                                                                                    
4515                                                                                                          
4516     /**                                                                                                  
4517      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4518      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4519      */                                                                                                  
4520     private boolean shouldShowIntroScreen() {                                                            
4521         return hasDismissableIntroScreen() &&                                                            
4522                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4523     }                                                                                                    
4524                                                                                                          
4525     protected void showIntroScreen() {                                                                   
4526         View introScreen = getIntroScreen();                                                             
4527         changeWallpaperVisiblity(false);                                                                 
4528         if (introScreen != null) {                                                                       
4529             mDragLayer.showOverlayView(introScreen);                                                     
4530         }                                                                                                
4531         if (mLauncherOverlayContainer != null) {                                                         
4532             mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                     
4533         }                                                                                                
4534     }                                                                                                    
4535                                                                                                          
4536     public void dismissIntroScreen() {                                                                   
4537         markIntroScreenDismissed();                                                                      
4538         if (showFirstRunActivity()) {                                                                    
4539             // We delay hiding the intro view until the first run activity is showing. This              
4540             // avoids a blip.                                                                            
4541             mWorkspace.postDelayed(new Runnable() {                                                      
4542                 @Override                                                                                
4543                 public void run() {                                                                      
4544                     mDragLayer.dismissOverlayView();                                                     
4545                     if (mLauncherOverlayContainer != null) {                                             
4546                         mLauncherOverlayContainer.setVisibility(View.VISIBLE);                           
4547                     }                                                                                    
4548                     showFirstRunClings();                                                                
4549                 }                                                                                        
4550             }, ACTIVITY_START_DELAY);                                                                    
4551         } else {                                                                                         
4552             mDragLayer.dismissOverlayView();                                                             
4553             if (mLauncherOverlayContainer != null) {                                                     
4554                 mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                   
4555             }                                                                                            
4556             showFirstRunClings();                                                                        
4557         }                                                                                                
4558         changeWallpaperVisiblity(true);                                                                  
4559     }                                                                                                    
4560                                                                                                          
4561     private void markIntroScreenDismissed() {                                                            
4562         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4563         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
4564         editor.apply();                                                                                  
4565     }                                                                                                    
4566                                                                                                          
4567     @Thunk void showFirstRunClings() {                                                                   
4568         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
4569         // on the device, then we always show the first run cling experience (or if there is no          
4570         // launcher2). Otherwise, we prompt the user upon started for migration                          
4571         LauncherClings launcherClings = new LauncherClings(this);                                        
4572         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
4573             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
4574                 launcherClings.showMigrationCling();                                                     
4575             } else {                                                                                     
4576                 launcherClings.showLongPressCling(true);                                                 
4577             }                                                                                            
4578         }                                                                                                
4579     }                                                                                                    
4580                                                                                                          
4581     void showWorkspaceSearchAndHotseat() {                                                               
4582         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
4583         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
4584         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
4585         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
4586     }                                                                                                    
4587                                                                                                          
4588     void hideWorkspaceSearchAndHotseat() {                                                               
4589         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
4590         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
4591         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
4592         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
4593     }                                                                                                    
4594                                                                                                          
4595     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
4596         // Called from search suggestion, not supported in other profiles.                               
4597         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
4598         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
4599         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,          
4600                 myUser);                                                                                 
4601         if (activityInfo == null) {                                                                      
4602             return null;                                                                                 
4603         }                                                                                                
4604         return new AppInfo(this, activityInfo, myUser, mIconCache);                                      
4605     }                                                                                                    
4606                                                                                                          
4607     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4608             Bitmap icon) {                                                                               
4609         // Called from search suggestion, not supported in other profiles.                               
4610         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
4611                 UserHandleCompat.myUserHandle());                                                        
4612     }                                                                                                    
4613                                                                                                          
4614     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4615             Bitmap icon, UserHandleCompat user) {                                                        
4616         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
4617         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
4618         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
4619     }                                                                                                    
4620                                                                                                          
4621     protected void moveWorkspaceToDefaultScreen() {                                                      
4622         mWorkspace.moveToDefaultScreen(false);                                                           
4623     }                                                                                                    
4624                                                                                                          
4625     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
4626         dragView.setTag(dragInfo);                                                                       
4627         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
4628         mWorkspace.beginExternalDragShared(dragView, source);                                            
4629     }                                                                                                    
4630                                                                                                          
4631     @Override                                                                                            
4632     public void onPageSwitch(View newPage, int newPageIndex) {                                           
4633         if (mLauncherCallbacks != null) {                                                                
4634             mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                      
4635         }                                                                                                
4636     }                                                                                                    
4637                                                                                                          
4638     /**                                                                                                  
4639      * Prints out out state for debugging.                                                               
4640      */                                                                                                  
4641     public void dumpState() {                                                                            
4642         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
4643         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
4644         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
4645         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
4646         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
4647         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
4648         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
4649         mModel.dumpState();                                                                              
4650         // TODO(hyunyoungs): add mWidgetsView.dumpState(); or mWidgetsModel.dumpState();                 
4651                                                                                                          
4652         Log.d(TAG, "END launcher3 dump state");                                                          
4653     }                                                                                                    
4654                                                                                                          
4655     @Override                                                                                            
4656     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
4657         super.dump(prefix, fd, writer, args);                                                            
4658         synchronized (sDumpLogs) {                                                                       
4659             writer.println(" ");                                                                         
4660             writer.println("Debug logs: ");                                                              
4661             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
4662                 writer.println("  " + sDumpLogs.get(i));                                                 
4663             }                                                                                            
4664         }                                                                                                
4665         if (mLauncherCallbacks != null) {                                                                
4666             mLauncherCallbacks.dump(prefix, fd, writer, args);                                           
4667         }                                                                                                
4668     }                                                                                                    
4669                                                                                                          
4670     public static void dumpDebugLogsToConsole() {                                                        
4671         if (DEBUG_DUMP_LOG) {                                                                            
4672             synchronized (sDumpLogs) {                                                                   
4673                 Log.d(TAG, "");                                                                          
4674                 Log.d(TAG, "*********************");                                                     
4675                 Log.d(TAG, "Launcher debug logs: ");                                                     
4676                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
4677                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
4678                 }                                                                                        
4679                 Log.d(TAG, "*********************");                                                     
4680                 Log.d(TAG, "");                                                                          
4681             }                                                                                            
4682         }                                                                                                
4683     }                                                                                                    
4684                                                                                                          
4685     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
4686         addDumpLog(tag, log, null, debugLog);                                                            
4687     }                                                                                                    
4688                                                                                                          
4689     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
4690         if (debugLog) {                                                                                  
4691             if (e != null) {                                                                             
4692                 Log.d(tag, log, e);                                                                      
4693             } else {                                                                                     
4694                 Log.d(tag, log);                                                                         
4695             }                                                                                            
4696         }                                                                                                
4697         if (DEBUG_DUMP_LOG) {                                                                            
4698             sDateStamp.setTime(System.currentTimeMillis());                                              
4699             synchronized (sDumpLogs) {                                                                   
4700                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
4701                     + (e == null ? "" : (", Exception: " + e)));                                         
4702             }                                                                                            
4703         }                                                                                                
4704     }                                                                                                    
4705                                                                                                          
4706     public static CustomAppWidget getCustomAppWidget(String name) {                                      
4707         return sCustomAppWidgets.get(name);                                                              
4708     }                                                                                                    
4709                                                                                                          
4710     public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                               
4711         return sCustomAppWidgets;                                                                        
4712     }                                                                                                    
4713                                                                                                          
4714     public void dumpLogsToLocalData() {                                                                  
4715         if (DEBUG_DUMP_LOG) {                                                                            
4716             new AsyncTask<Void, Void, Void>() {                                                          
4717                 public Void doInBackground(Void ... args) {                                              
4718                     boolean success = false;                                                             
4719                     sDateStamp.setTime(sRunStart);                                                       
4720                     String FILENAME = sDateStamp.getMonth() + "-"                                        
4721                             + sDateStamp.getDay() + "_"                                                  
4722                             + sDateStamp.getHours() + "-"                                                
4723                             + sDateStamp.getMinutes() + "_"                                              
4724                             + sDateStamp.getSeconds() + ".txt";                                          
4725                                                                                                          
4726                     FileOutputStream fos = null;                                                         
4727                     File outFile = null;                                                                 
4728                     try {                                                                                
4729                         outFile = new File(getFilesDir(), FILENAME);                                     
4730                         outFile.createNewFile();                                                         
4731                         fos = new FileOutputStream(outFile);                                             
4732                     } catch (Exception e) {                                                              
4733                         e.printStackTrace();                                                             
4734                     }                                                                                    
4735                     if (fos != null) {                                                                   
4736                         PrintWriter writer = new PrintWriter(fos);                                       
4737                                                                                                          
4738                         writer.println(" ");                                                             
4739                         writer.println("Debug logs: ");                                                  
4740                         synchronized (sDumpLogs) {                                                       
4741                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
4742                                 writer.println("  " + sDumpLogs.get(i));                                 
4743                             }                                                                            
4744                         }                                                                                
4745                         writer.close();                                                                  
4746                     }                                                                                    
4747                     try {                                                                                
4748                         if (fos != null) {                                                               
4749                             fos.close();                                                                 
4750                             success = true;                                                              
4751                         }                                                                                
4752                     } catch (IOException e) {                                                            
4753                         e.printStackTrace();                                                             
4754                     }                                                                                    
4755                     return null;                                                                         
4756                 }                                                                                        
4757             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
4758         }                                                                                                
4759     }                                                                                                    
4760 }                                                                                                        
4761                                                                                                          
4762 interface LauncherTransitionable {                                                                       
4763     View getContent();                                                                                   
4764     void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                 
4765     void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                   
4766     void onLauncherTransitionStep(Launcher l, float t);                                                  
4767     void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                     
4768 }                                                                                                        
4769                                                                                                          
4770 interface DebugIntents {                                                                                 
4771     static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                
4772     static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";              
4773 }                                                                                                        



   1 /*                                                                                                       
   2  * Copyright (C) 2008 The Android Open Source Project                                                    
   3  *                                                                                                       
   4  * Licensed under the Apache License, Version 2.0 (the "License");                                       
   5  * you may not use this file except in compliance with the License.                                      
   6  * You may obtain a copy of the License at                                                               
   7  *                                                                                                       
   8  *      http://www.apache.org/licenses/LICENSE-2.0                                                       
   9  *                                                                                                       
  10  * Unless required by applicable law or agreed to in writing, software                                   
  11  * distributed under the License is distributed on an "AS IS" BASIS,                                     
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                              
  13  * See the License for the specific language governing permissions and                                   
  14  * limitations under the License.                                                                        
  15  */                                                                                                      
  16 package com.android.launcher3;                                                                           
  17                                                                                                          
  18 import android.animation.Animator;                                                                       
  19 import android.animation.AnimatorListenerAdapter;                                                        
  20 import android.animation.AnimatorSet;                                                                    
  21 import android.animation.ObjectAnimator;                                                                 
  22 import android.animation.PropertyValuesHolder;                                                           
  23 import android.animation.ValueAnimator;                                                                  
  24 import android.annotation.TargetApi;                                                                     
  25 import android.app.Activity;                                                                             
  26 import android.app.ActivityManager;                                                                      
  27 import android.app.ActivityOptions;                                                                      
  28 import android.app.AlertDialog;                                                                          
  29 import android.app.SearchManager;                                                                        
  30 import android.appwidget.AppWidgetHostView;                                                              
  31 import android.appwidget.AppWidgetManager;                                                               
  32 import android.appwidget.AppWidgetProviderInfo;                                                          
  33 import android.content.ActivityNotFoundException;                                                        
  34 import android.content.BroadcastReceiver;                                                                
  35 import android.content.ComponentCallbacks2;                                                              
  36 import android.content.ComponentName;                                                                    
  37 import android.content.ContentResolver;                                                                  
  38 import android.content.Context;                                                                          
  39 import android.content.DialogInterface;                                                                  
  40 import android.content.Intent;                                                                           
  41 import android.content.IntentFilter;                                                                     
  42 import android.content.IntentSender;                                                                     
  43 import android.content.SharedPreferences;                                                                
  44 import android.content.pm.ActivityInfo;                                                                  
  45 import android.content.pm.ApplicationInfo;                                                               
  46 import android.content.pm.PackageManager.NameNotFoundException;                                          
  47 import android.content.pm.PackageManager;                                                                
  48 import android.content.res.Configuration;                                                                
  49 import android.database.ContentObserver;                                                                 
  50 import android.database.sqlite.SQLiteDatabase;                                                           
  51 import android.graphics.Bitmap;                                                                          
  52 import android.graphics.Canvas;                                                                          
  53 import android.graphics.Color;                                                                           
  54 import android.graphics.PorterDuff;                                                                      
  55 import android.graphics.Rect;                                                                            
  56 import android.graphics.drawable.Drawable;                                                               
  57 import android.net.Uri;                                                                                  
  58 import android.os.AsyncTask;                                                                             
  59 import android.os.Build;                                                                                 
  60 import android.os.Bundle;                                                                                
  61 import android.os.Environment;                                                                           
  62 import android.os.Handler;                                                                               
  63 import android.os.Message;                                                                               
  64 import android.os.StrictMode;                                                                            
  65 import android.os.SystemClock;                                                                           
  66 import android.text.Selection;                                                                           
  67 import android.text.SpannableStringBuilder;                                                              
  68 import android.text.TextUtils;                                                                           
  69 import android.text.method.TextKeyListener;                                                              
  70 import android.util.Log;                                                                                 
  71 import android.view.Display;                                                                             
  72 import android.view.Gravity;                                                                             
  73 import android.view.HapticFeedbackConstants;                                                             
  74 import android.view.KeyEvent;                                                                            
  75 import android.view.LayoutInflater;                                                                      
  76 import android.view.Menu;                                                                                
  77 import android.view.MotionEvent;                                                                         
  78 import android.view.Surface;                                                                             
  79 import android.view.View.OnClickListener;                                                                
  80 import android.view.View.OnLongClickListener;                                                            
  81 import android.view.View;                                                                                
  82 import android.view.ViewGroup;                                                                           
  83 import android.view.ViewStub;                                                                            
  84 import android.view.ViewTreeObserver;                                                                    
  85 import android.view.Window;                                                                              
  86 import android.view.WindowManager;                                                                       
  87 import android.view.accessibility.AccessibilityEvent;                                                    
  88 import android.view.inputmethod.InputMethodManager;                                                      
  89 import android.widget.Advanceable;                                                                       
  90 import android.widget.FrameLayout;                                                                       
  91 import android.widget.ImageView;                                                                         
  92 import android.widget.TextView;                                                                          
  93 import android.widget.Toast;                                                                             
  94 import com.android.launcher3.DropTarget.DragObject;                                                      
  95 import com.android.launcher3.PagedView.PageSwitchListener;                                               
  96 import com.android.launcher3.compat.AppWidgetManagerCompat;                                              
  97 import com.android.launcher3.compat.LauncherActivityInfoCompat;                                          
  98 import com.android.launcher3.compat.LauncherAppsCompat;                                                  
  99 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                           
 100 import com.android.launcher3.compat.PackageInstallerCompat;                                              
 101 import com.android.launcher3.compat.UserHandleCompat;                                                    
 102 import com.android.launcher3.compat.UserManagerCompat;                                                   
 103 import com.android.launcher3.util.Thunk;                                                                 
 104 import com.android.launcher3.widget.PendingAddWidgetInfo;                                                
 105 import com.android.launcher3.widget.WidgetsContainerView;                                                
 106 import java.io.DataInputStream;                                                                          
 107 import java.io.DataOutputStream;                                                                         
 108 import java.io.File;                                                                                     
 109 import java.io.FileDescriptor;                                                                           
 110 import java.io.FileNotFoundException;                                                                    
 111 import java.io.FileOutputStream;                                                                         
 112 import java.io.IOException;                                                                              
 113 import java.io.PrintWriter;                                                                              
 114 import java.lang.reflect.InvocationTargetException;                                                      
 115 import java.lang.reflect.Method;                                                                         
 116 import java.text.DateFormat;                                                                             
 117 import java.util.ArrayList;                                                                              
 118 import java.util.Collection;                                                                             
 119 import java.util.Date;                                                                                   
 120 import java.util.HashMap;                                                                                
 121 import java.util.HashSet;                                                                                
 122 import java.util.List;                                                                                   
 123 import java.util.concurrent.atomic.AtomicInteger;                                                        
 124                                                                                                          
 125                                                                                                          
 126 interface DebugIntents {                                                                                 
 127     public static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";         
 128                                                                                                          
 129     public static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";       
 130 }                                                                                                        
 131                                                                                                          
 132 /**                                                                                                      
 133  * Default launcher application.                                                                         
 134  */                                                                                                      
 135 public class Launcher extends Activity implements View.OnClickListener , OnLongClickListener , LauncherMo🔵
 136     static final String TAG = "Launcher";                                                                
 137                                                                                                          
 138     static final boolean LOGD = true;                                                                    
 139                                                                                                          
 140     static final boolean PROFILE_STARTUP = false;                                                        
 141                                                                                                          
 142     static final boolean DEBUG_WIDGETS = true;                                                           
 143                                                                                                          
 144     static final boolean DEBUG_STRICT_MODE = false;                                                      
 145                                                                                                          
 146     static final boolean DEBUG_RESUME_TIME = false;                                                      
 147                                                                                                          
 148     static final boolean DEBUG_DUMP_LOG = false;                                                         
 149                                                                                                          
 150     // allow DebugIntents to run                                                                         
 151     static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                      
 152                                                                                                          
 153     private static final int REQUEST_CREATE_SHORTCUT = 1;                                                
 154                                                                                                          
 155     private static final int REQUEST_CREATE_APPWIDGET = 5;                                               
 156                                                                                                          
 157     private static final int REQUEST_PICK_APPWIDGET = 9;                                                 
 158                                                                                                          
 159     private static final int REQUEST_PICK_WALLPAPER = 10;                                                
 160                                                                                                          
 161     private static final int REQUEST_BIND_APPWIDGET = 11;                                                
 162                                                                                                          
 163     private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                         
 164                                                                                                          
 165     /**                                                                                                  
 166      * IntentStarter uses request codes starting with this. This must be greater than all activity       
 167      * request codes used internally.                                                                    
 168      */                                                                                                  
 169     protected static final int REQUEST_LAST = 100;                                                       
 170                                                                                                          
 171     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                          
 172                                                                                                          
 173     static final int SCREEN_COUNT = 5;                                                                   
 174                                                                                                          
 175     // To turn on these properties, type                                                                 
 176     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                      
 177     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                     
 178                                                                                                          
 179     // The Intent extra that defines whether to ignore the launch animation                              
 180     // The Intent extra that defines whether to ignore the launch animation                              
 181     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                           
 182             "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                       
 183                                                                                                          
 184     // Type: int                                                                                         
 185     // Type: int                                                                                         
 186     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                
 187                                                                                                          
 188     // Type: int                                                                                         
 189     // Type: int                                                                                         
 190     private static final String RUNTIME_STATE = "launcher.state";                                        
 191                                                                                                          
 192     // Type: int                                                                                         
 193     // Type: int                                                                                         
 194     private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";          
 195                                                                                                          
 196     // Type: int                                                                                         
 197     // Type: int                                                                                         
 198     private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                
 199                                                                                                          
 200     // Type: int                                                                                         
 201     // Type: int                                                                                         
 202     private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                
 203                                                                                                          
 204     // Type: int                                                                                         
 205     // Type: int                                                                                         
 206     private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                
 207                                                                                                          
 208     // Type: boolean                                                                                     
 209     // Type: boolean                                                                                     
 210     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";          
 211                                                                                                          
 212     // Type: long                                                                                        
 213     // Type: long                                                                                        
 214     private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";    
 215                                                                                                          
 216     // Type: int                                                                                         
 217     // Type: int                                                                                         
 218     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                
 219                                                                                                          
 220     // Type: int                                                                                         
 221     // Type: int                                                                                         
 222     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                
 223                                                                                                          
 224     // Type: parcelable                                                                                  
 225     // Type: parcelable                                                                                  
 226     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";      
 227                                                                                                          
 228     // Type: parcelable                                                                                  
 229     // Type: parcelable                                                                                  
 230     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";          
 231                                                                                                          
 232     // Type: int[]                                                                                       
 233     // Type: int[]                                                                                       
 234     private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                            
 235                                                                                                          
 236     static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                      
 237                                                                                                          
 238     static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";          
 239                                                                                                          
 240     static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                            
 241                                                                                                          
 242     static final String ACTION_FIRST_LOAD_COMPLETE =                                                     
 243             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                          
 244                                                                                                          
 245     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                   
 246                                                                                                          
 247     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                     
 248                                                                                                          
 249     private static final String QSB_WIDGET_ID = "qsb_widget_id";                                         
 250                                                                                                          
 251     private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                             
 252                                                                                                          
 253     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";               
 254                                                                                                          
 255     /** The different states that Launcher can be in. */                                                 
 256     enum State {                                                                                         
 257                                                                                                          
 258     NONE,                                                                                                
 259     WORKSPACE,                                                                                           
 260         APPS,                                                                                            
 261         APPS_SPRING_LOADED,                                                                              
 262         WIDGETS,                                                                                         
 263         WIDGETS_SPRING_LOADED;}                                                                          
 264                                                                                                          
 265     @Thunk                                                                                               
 266     State mState = State.WORKSPACE;                                                                      
 267                                                                                                          
 268     @Thunk                                                                                               
 269     AnimatorSet mStateAnimation;                                                                         
 270                                                                                                          
 271     @Thunk                                                                                               
 272     LauncherStateTransitionAnimation mStateTransitionAnimation;                                          
 273                                                                                                          
 274     private boolean mIsSafeModeEnabled;                                                                  
 275                                                                                                          
 276     LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();             
 277                                                                                                          
 278     LauncherOverlay mLauncherOverlay;                                                                    
 279                                                                                                          
 280     InsettableFrameLayout mLauncherOverlayContainer;                                                     
 281                                                                                                          
 282     static final int APPWIDGET_HOST_ID = 1024;                                                           
 283                                                                                                          
 284     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                  
 285                                                                                                          
 286     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                   
 287                                                                                                          
 288     private static final int ACTIVITY_START_DELAY = 1000;                                                
 289                                                                                                          
 290     private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                 
 291                                                                                                          
 292     private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                          
 293                                                                                                          
 294     // How long to wait before the new-shortcut animation automatically pans the workspace               
 295     // How long to wait before the new-shortcut animation automatically pans the workspace               
 296     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                   
 297                                                                                                          
 298     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                  
 299                                                                                                          
 300     @Thunk                                                                                               
 301     static int NEW_APPS_ANIMATION_DELAY = 500;                                                           
 302                                                                                                          
 303     private final BroadcastReceiver mCloseSystemDialogsReceiver                                          
 304             = new CloseSystemDialogsIntentReceiver();                                                    
 305                                                                                                          
 306     private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                        
 307                                                                                                          
 308     private LayoutInflater mInflater;                                                                    
 309                                                                                                          
 310     @Thunk                                                                                               
 311     Workspace mWorkspace;                                                                                
 312                                                                                                          
 313     private View mLauncherView;                                                                          
 314                                                                                                          
 315     private View mPageIndicators;                                                                        
 316                                                                                                          
 317     @Thunk                                                                                               
 318     DragLayer mDragLayer;                                                                                
 319                                                                                                          
 320     private DragController mDragController;                                                              
 321                                                                                                          
 322     private View mWeightWatcher;                                                                         
 323                                                                                                          
 324     private AppWidgetManagerCompat mAppWidgetManager;                                                    
 325                                                                                                          
 326     private LauncherAppWidgetHost mAppWidgetHost;                                                        
 327                                                                                                          
 328     @Thunk                                                                                               
 329     ItemInfo mPendingAddInfo = new ItemInfo();                                                           
 330                                                                                                          
 331     private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                         
 332                                                                                                          
 333     private int mPendingAddWidgetId = -1;                                                                
 334                                                                                                          
 335     private int[] mTmpAddItemCellCoordinates = new int[2];                                               
 336                                                                                                          
 337     private FolderInfo mFolderInfo;                                                                      
 338                                                                                                          
 339     private Hotseat mHotseat;                                                                            
 340                                                                                                          
 341     private ViewGroup mOverviewPanel;                                                                    
 342                                                                                                          
 343     private View mAllAppsButton;                                                                         
 344                                                                                                          
 345     private SearchDropTargetBar mSearchDropTargetBar;                                                    
 346                                                                                                          
 347     // Main container view for the all apps screen.                                                      
 348     @Thunk                                                                                               
 349     AppsContainerView mAppsView;                                                                         
 350                                                                                                          
 351     // Main container view for the widget tray screen.                                                   
 352     private WidgetsContainerView mWidgetsView;                                                           
 353                                                                                                          
 354     private boolean mAutoAdvanceRunning = false;                                                         
 355                                                                                                          
 356     private AppWidgetHostView mQsb;                                                                      
 357                                                                                                          
 358     private Bundle mSavedState;                                                                          
 359                                                                                                          
 360     // We set the state in both onCreate and then onNewIntent in some cases, which causes both           
 361     // scroll issues (because the workspace may not have been measured yet) and extra work.              
 362     // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.      
 363     private State mOnResumeState = State.NONE;                                                           
 364                                                                                                          
 365     private SpannableStringBuilder mDefaultKeySsb = null;                                                
 366                                                                                                          
 367     @Thunk                                                                                               
 368     boolean mWorkspaceLoading = true;                                                                    
 369                                                                                                          
 370     private boolean mPaused = true;                                                                      
 371                                                                                                          
 372     private boolean mRestoring;                                                                          
 373                                                                                                          
 374     private boolean mWaitingForResult;                                                                   
 375                                                                                                          
 376     private boolean mOnResumeNeedsLoad;                                                                  
 377                                                                                                          
 378     private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                      
 379                                                                                                          
 380     private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                          
 381                                                                                                          
 382     private Bundle mSavedInstanceState;                                                                  
 383                                                                                                          
 384     private LauncherModel mModel;                                                                        
 385                                                                                                          
 386     private IconCache mIconCache;                                                                        
 387                                                                                                          
 388     @Thunk                                                                                               
 389     boolean mUserPresent = true;                                                                         
 390                                                                                                          
 391     private boolean mVisible = false;                                                                    
 392                                                                                                          
 393     private boolean mHasFocus = false;                                                                   
 394                                                                                                          
 395     private boolean mAttached = false;                                                                   
 396                                                                                                          
 397     @Thunk                                                                                               
 398     static LocaleConfiguration sLocaleConfiguration = null;                                              
 399                                                                                                          
 400     private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                 
 401                                                                                                          
 402     private View.OnTouchListener mHapticFeedbackTouchListener;                                           
 403                                                                                                          
 404     // Related to the auto-advancing of widgets                                                          
 405     // Related to the auto-advancing of widgets                                                          
 406     private final int ADVANCE_MSG = 1;                                                                   
 407                                                                                                          
 408     private final int mAdvanceInterval = 20000;                                                          
 409                                                                                                          
 410     private final int mAdvanceStagger = 250;                                                             
 411                                                                                                          
 412     private long mAutoAdvanceSentTime;                                                                   
 413                                                                                                          
 414     private long mAutoAdvanceTimeLeft = -1;                                                              
 415                                                                                                          
 416     @Thunk                                                                                               
 417     HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance = new HashMap<View, AppWidgetProviderInfo>(); 
 418                                                                                                          
 419     // Determines how long to wait after a rotation before restoring the screen orientation to           
 420     // match the sensor state.                                                                           
 421     // Determines how long to wait after a rotation before restoring the screen orientation to           
 422     // match the sensor state.                                                                           
 423     private final int mRestoreScreenOrientationDelay = 500;                                              
 424                                                                                                          
 425     @Thunk                                                                                               
 426     Drawable mWorkspaceBackgroundDrawable;                                                               
 427                                                                                                          
 428     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                
 429                                                                                                          
 430     private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                       
 431                                                                                                          
 432     static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                  
 433                                                                                                          
 434     static Date sDateStamp = new Date();                                                                 
 435                                                                                                          
 436     static DateFormat sDateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);  
 437                                                                                                          
 438     static long sRunStart = System.currentTimeMillis();                                                  
 439                                                                                                          
 440     static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                               
 441                                                                                                          
 442     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 443     // it from the context.                                                                              
 444     // We only want to get the SharedPreferences once since it does an FS stat each time we get          
 445     // it from the context.                                                                              
 446     private SharedPreferences mSharedPrefs;                                                              
 447                                                                                                          
 448     // Holds the page that we need to animate to, and the icon views that we need to animate up          
 449     // when we scroll to that page on resume.                                                            
 450     @Thunk                                                                                               
 451     ImageView mFolderIconImageView;                                                                      
 452                                                                                                          
 453     private Bitmap mFolderIconBitmap;                                                                    
 454                                                                                                          
 455     private Canvas mFolderIconCanvas;                                                                    
 456                                                                                                          
 457     private Rect mRectForFolderAnimation = new Rect();                                                   
 458                                                                                                          
 459     private BubbleTextView mWaitingForResume;                                                            
 460                                                                                                          
 461     protected static HashMap<String, CustomAppWidget> sCustomAppWidgets = new HashMap<String, CustomAppWi🔵
 462                                                                                                          
 463     private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                      
 464                                                                                                          
 465     static {                                                                                             
 466         if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                 
 467             sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                       
 468         }                                                                                                
 469     }                                                                                                    
 470                                                                                                          
 471     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 472     // TODO: remove this field and call method directly when Launcher3 can depend on M APIs              
 473     private static Method sClipRevealMethod = null;                                                      
 474                                                                                                          
 475     static {                                                                                             
 476         Class<?> activityOptionsClass = ActivityOptions.class;                                           
 477         try {                                                                                            
 478             sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation", View.cl🔵
 479         } catch (java.lang.Exception e) {                                                                
 480             // Earlier version                                                                           
 481         }                                                                                                
 482     }                                                                                                    
 483                                                                                                          
 484     @Thunk                                                                                               
 485     Runnable mBuildLayersRunnable = new Runnable() {                                                     
 486         public void run() {                                                                              
 487             if (mWorkspace != null) {                                                                    
 488                 mWorkspace.buildPageHardwareLayers();                                                    
 489             }                                                                                            
 490         }                                                                                                
 491     };                                                                                                   
 492                                                                                                          
 493     private static PendingAddArguments sPendingAddItem;                                                  
 494                                                                                                          
 495     @Thunk                                                                                               
 496     static class PendingAddArguments {                                                                   
 497         int requestCode;                                                                                 
 498                                                                                                          
 499         Intent intent;                                                                                   
 500                                                                                                          
 501         long container;                                                                                  
 502                                                                                                          
 503         long screenId;                                                                                   
 504                                                                                                          
 505         int cellX;                                                                                       
 506                                                                                                          
 507         int cellY;                                                                                       
 508                                                                                                          
 509         int appWidgetId;                                                                                 
 510     }                                                                                                    
 511                                                                                                          
 512     private Stats mStats;                                                                                
 513                                                                                                          
 514     FocusIndicatorView mFocusHandler;                                                                    
 515                                                                                                          
 516     @Override                                                                                            
 517     protected void onCreate(Bundle savedInstanceState) {                                                 
 518         if (DEBUG_STRICT_MODE) {                                                                         
 519             StrictMode.setThreadPolicy(// or .detectAll() for all detectable problems                    
 520             new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().pe🔵
 521             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectL🔵
 522         }                                                                                                
 523         if (mLauncherCallbacks != null) {                                                                
 524             mLauncherCallbacks.preOnCreate();                                                            
 525         }                                                                                                
 526         super.onCreate(savedInstanceState);                                                              
 527         LauncherAppState.setApplicationContext(getApplicationContext());                                 
 528         LauncherAppState app = LauncherAppState.getInstance();                                           
 529         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                  
 530         // Lazy-initialize the dynamic grid                                                              
 531         DeviceProfile grid = app.initDynamicGrid(this);                                                  
 532         // the LauncherApplication should call this, but in case of Instrumentation it might not be prese🔵
 533         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIV🔵
 534         mIsSafeModeEnabled = getPackageManager().isSafeMode();                                           
 535         mModel = app.setLauncher(this);                                                                  
 536         mIconCache = app.getIconCache();                                                                 
 537         mIconCache.flushInvalidIcons(grid);                                                              
 538         mDragController = new DragController(this);                                                      
 539         mInflater = getLayoutInflater();                                                                 
 540         mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                    
 541         mStats = new Stats(this);                                                                        
 542         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                    
 543         mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                             
 544         mAppWidgetHost.startListening();                                                                 
 545         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,       
 546         // this also ensures that any synchronous binding below doesn't re-trigger another               
 547         // LauncherModel load.                                                                           
 548         mPaused = false;                                                                                 
 549         if (PROFILE_STARTUP) {                                                                           
 550             android.os.Debug.startMethodTracing(Environment.getExternalStorageDirectory() + "/launcher");
 551         }                                                                                                
 552         checkForLocaleChange();                                                                          
 553         setContentView(R.layout.launcher);                                                               
 554         setupViews();                                                                                    
 555         grid.layout(this);                                                                               
 556         registerContentObservers();                                                                      
 557         lockAllApps();                                                                                   
 558         mSavedState = savedInstanceState;                                                                
 559         restoreState(mSavedState);                                                                       
 560         if (PROFILE_STARTUP) {                                                                           
 561             android.os.Debug.stopMethodTracing();                                                        
 562         }                                                                                                
 563         if (!mRestoring) {                                                                               
 564             if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                              
 565                 // If the user leaves launcher, then we should just load items asynchronously when       
 566                 // they return.                                                                          
 567                 mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                
 568             } else {                                                                                     
 569                 // We only load the page synchronously if the user rotates (or triggers a                
 570                 // configuration change) while launcher is in the foreground                             
 571                 mModel.startLoader(true, mWorkspace.getRestorePage());                                   
 572             }                                                                                            
 573         }                                                                                                
 574         // For handling default keys                                                                     
 575         mDefaultKeySsb = new SpannableStringBuilder();                                                   
 576         Selection.setSelection(mDefaultKeySsb, 0);                                                       
 577         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                      
 578         registerReceiver(mCloseSystemDialogsReceiver, filter);                                           
 579         // On large interfaces, we want the screen to auto-rotate based on the current orientation       
 580         unlockScreenOrientation(true);                                                                   
 581         if (mLauncherCallbacks != null) {                                                                
 582             mLauncherCallbacks.onCreate(savedInstanceState);                                             
 583             if (mLauncherCallbacks.hasLauncherOverlay()) {                                               
 584                 ViewStub stub = ((ViewStub) (findViewById(R.id.launcher_overlay_stub)));                 
 585                 mLauncherOverlayContainer = ((InsettableFrameLayout) (stub.inflate()));                  
 586                 mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(mLauncherOverlayContainer, m🔵
 587                 mWorkspace.setLauncherOverlay(mLauncherOverlay);                                         
 588             }                                                                                            
 589         }                                                                                                
 590         if (shouldShowIntroScreen()) {                                                                   
 591             showIntroScreen();                                                                           
 592         } else {                                                                                         
 593             showFirstRunActivity();                                                                      
 594             showFirstRunClings();                                                                        
 595         }                                                                                                
 596     }                                                                                                    
 597                                                                                                          
 598     private LauncherCallbacks mLauncherCallbacks;                                                        
 599                                                                                                          
 600     public void onPostCreate(Bundle savedInstanceState) {                                                
 601         super.onPostCreate(savedInstanceState);                                                          
 602         if (mLauncherCallbacks != null) {                                                                
 603             mLauncherCallbacks.onPostCreate(savedInstanceState);                                         
 604         }                                                                                                
 605     }                                                                                                    
 606                                                                                                          
 607     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                   
 608         mLauncherCallbacks = callbacks;                                                                  
 609         mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {                
 610             @Override                                                                                    
 611             public void onAllAppsBoundsChanged(Rect bounds) {                                            
 612                 mAppsView.setFixedBounds(Launcher.this, bounds);                                         
 613             }                                                                                            
 614                                                                                                          
 615             @Override                                                                                    
 616             public void dismissAllApps() {                                                               
 617                 showWorkspace(true);                                                                     
 618             }                                                                                            
 619         });                                                                                              
 620         return true;                                                                                     
 621     }                                                                                                    
 622                                                                                                          
 623     @Override                                                                                            
 624     public void onLauncherProviderChange() {                                                             
 625         if (mLauncherCallbacks != null) {                                                                
 626             mLauncherCallbacks.onLauncherProviderChange();                                               
 627         }                                                                                                
 628     }                                                                                                    
 629                                                                                                          
 630     /** To be overridden by subclasses to hint to Launcher that we have custom content */                
 631     protected boolean hasCustomContentToLeft() {                                                         
 632         if (mLauncherCallbacks != null) {                                                                
 633             return mLauncherCallbacks.hasCustomContentToLeft();                                          
 634         }                                                                                                
 635         return false;                                                                                    
 636     }                                                                                                    
 637                                                                                                          
 638     /**                                                                                                  
 639      * To be overridden by subclasses to populate the custom content container and call                  
 640      * {@link #addToCustomContentPage}. This will only be invoked if                                     
 641      * {@link #hasCustomContentToLeft()} is {@code true}.                                                
 642      */                                                                                                  
 643     protected void populateCustomContentContainer() {                                                    
 644         if (mLauncherCallbacks != null) {                                                                
 645             mLauncherCallbacks.populateCustomContentContainer();                                         
 646         }                                                                                                
 647     }                                                                                                    
 648                                                                                                          
 649     /**                                                                                                  
 650      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to          
 651      * ensure the custom content page is added or removed if necessary.                                  
 652      */                                                                                                  
 653     protected void invalidateHasCustomContentToLeft() {                                                  
 654         if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                               
 655             // Not bound yet, wait for bindScreens to be called.                                         
 656             return;                                                                                      
 657         }                                                                                                
 658                                                                                                          
 659         if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                
 660             // Create the custom content page and call the subclass to populate it.                      
 661             mWorkspace.createCustomContentContainer();                                                   
 662             populateCustomContentContainer();                                                            
 663         } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                         
 664             mWorkspace.removeCustomContentPage();                                                        
 665         }                                                                                                
 666     }                                                                                                    
 667                                                                                                          
 668     @Thunk                                                                                               
 669     void checkForLocaleChange() {                                                                        
 670         if (sLocaleConfiguration == null) {                                                              
 671             new AsyncTask<Void, Void, LocaleConfiguration>() {                                           
 672                 @Override                                                                                
 673                 protected LocaleConfiguration doInBackground(Void... unused) {                           
 674                     LocaleConfiguration localeConfiguration = new LocaleConfiguration();                 
 675                     readConfiguration(Launcher.this, localeConfiguration);                               
 676                     return localeConfiguration;                                                          
 677                 }                                                                                        
 678                                                                                                          
 679                 @Override                                                                                
 680                 protected void onPostExecute(LocaleConfiguration result) {                               
 681                     sLocaleConfiguration = result;                                                       
 682                     checkForLocaleChange();// recursive, but now with a locale configuration             
 683                                                                                                          
 684                 }                                                                                        
 685             }.execute();                                                                                 
 686             return;                                                                                      
 687         }                                                                                                
 688         final Configuration configuration = getResources().getConfiguration();                           
 689         final String previousLocale = Launcher.sLocaleConfiguration.locale;                              
 690         final String locale = configuration.locale.toString();                                           
 691         final int previousMcc = Launcher.sLocaleConfiguration.mcc;                                       
 692         final int mcc = configuration.mcc;                                                               
 693         final int previousMnc = Launcher.sLocaleConfiguration.mnc;                                       
 694         final int mnc = configuration.mnc;                                                               
 695         boolean localeChanged = ((!locale.equals(previousLocale)) || (mcc != previousMcc)) || (mnc != pre🔵
 696         if (localeChanged) {                                                                             
 697             Launcher.sLocaleConfiguration.locale = locale;                                               
 698             Launcher.sLocaleConfiguration.mcc = mcc;                                                     
 699             Launcher.sLocaleConfiguration.mnc = mnc;                                                     
 700             mIconCache.flush();                                                                          
 701             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                        
 702             new AsyncTask<Void, Void, Void>() {                                                          
 703                 public Void doInBackground(Void... args) {                                               
 704                     writeConfiguration(Launcher.this, localeConfiguration);                              
 705                     return null;                                                                         
 706                 }                                                                                        
 707             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void) (null)));                        
 708         }                                                                                                
 709     }                                                                                                    
 710                                                                                                          
 711     @Thunk                                                                                               
 712     static class LocaleConfiguration {                                                                   
 713         public String locale;                                                                            
 714                                                                                                          
 715         public int mcc = -1;                                                                             
 716                                                                                                          
 717         public int mnc = -1;                                                                             
 718     }                                                                                                    
 719                                                                                                          
 720     @Thunk                                                                                               
 721     static void readConfiguration(Context context, LocaleConfiguration configuration) {                  
 722         DataInputStream in = null;                                                                       
 723         try {                                                                                            
 724             in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));         
 725             configuration.locale = in.readUTF();                                                         
 726             configuration.mcc = in.readInt();                                                            
 727             configuration.mnc = in.readInt();                                                            
 728         } catch (FileNotFoundException e) {                                                              
 729             // Ignore                                                                                    
 730         } catch (IOException e) {                                                                        
 731             // Ignore                                                                                    
 732         } finally {                                                                                      
 733             if (in != null) {                                                                            
 734                 try {                                                                                    
 735                     in.close();                                                                          
 736                 } catch (IOException e) {                                                                
 737                     // Ignore                                                                            
 738                 }                                                                                        
 739             }                                                                                            
 740         }                                                                                                
 741     }                                                                                                    
 742                                                                                                          
 743     @Thunk                                                                                               
 744     static void writeConfiguration(Context context, LocaleConfiguration configuration) {                 
 745         DataOutputStream out = null;                                                                     
 746         try {                                                                                            
 747             out = new DataOutputStream(context.openFileOutput(LauncherFiles.LAUNCHER_PREFERENCES, MODE_PR🔵
 748             out.writeUTF(configuration.locale);                                                          
 749             out.writeInt(configuration.mcc);                                                             
 750             out.writeInt(configuration.mnc);                                                             
 751             out.flush();                                                                                 
 752         } catch (FileNotFoundException e) {                                                              
 753             // Ignore                                                                                    
 754         } catch (IOException e) {                                                                        
 755             // noinspection ResultOfMethodCallIgnored                                                    
 756             context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                      
 757         } finally {                                                                                      
 758             if (out != null) {                                                                           
 759                 try {                                                                                    
 760                     out.close();                                                                         
 761                 } catch (IOException e) {                                                                
 762                     // Ignore                                                                            
 763                 }                                                                                        
 764             }                                                                                            
 765         }                                                                                                
 766     }                                                                                                    
 767                                                                                                          
 768     public Stats getStats() {                                                                            
 769         return mStats;                                                                                   
 770     }                                                                                                    
 771                                                                                                          
 772     public LayoutInflater getInflater() {                                                                
 773         return mInflater;                                                                                
 774     }                                                                                                    
 775                                                                                                          
 776     public boolean isDraggingEnabled() {                                                                 
 777         // We prevent dragging when we are loading the workspace as it is possible to pick up a view     
 778         // that is subsequently removed from the workspace in startBinding().                            
 779         return !mModel.isLoadingWorkspace();                                                             
 780     }                                                                                                    
 781                                                                                                          
 782     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                       
 783     public static int generateViewId() {                                                                 
 784         if (Build.VERSION.SDK_INT >= 17) {                                                               
 785             return View.generateViewId();                                                                
 786         } else {                                                                                         
 787             // View.generateViewId() is not available. The following fallback logic is a copy            
 788             // of its implementation.                                                                    
 789             for (;;) {                                                                                   
 790                 final int result = sNextGeneratedId.get();                                               
 791                 // aapt-generated IDs have the high byte nonzero; clamp to the range under that.         
 792                 int newValue = result + 1;                                                               
 793                 if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                       
 794                 if (sNextGeneratedId.compareAndSet(result, newValue)) {                                  
 795                     return result;                                                                       
 796                 }                                                                                        
 797             }                                                                                            
 798         }                                                                                                
 799     }                                                                                                    
 800                                                                                                          
 801     public int getViewIdForItem(ItemInfo info) {                                                         
 802         // This cast is safe given the > 2B range for int.                                               
 803         int itemId = (int) info.id;                                                                      
 804         if (mItemIdToViewId.containsKey(itemId)) {                                                       
 805             return mItemIdToViewId.get(itemId);                                                          
 806         }                                                                                                
 807         int viewId = generateViewId();                                                                   
 808         mItemIdToViewId.put(itemId, viewId);                                                             
 809         return viewId;                                                                                   
 810     }                                                                                                    
 811                                                                                                          
 812     /**                                                                                                  
 813      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have         
 814      * a configuration step, this allows the proper animations to run after other transitions.           
 815      */                                                                                                  
 816     private long completeAdd(PendingAddArguments args) {                                                 
 817         long screenId = args.screenId;                                                                   
 818         if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                            
 819             // When the screen id represents an actual screen (as opposed to a rank) we make sure        
 820             // that the drop page actually exists.                                                       
 821             screenId = ensurePendingDropLayoutExists(args.screenId);                                     
 822         }                                                                                                
 823                                                                                                          
 824         switch (args.requestCode) {                                                                      
 825             case REQUEST_CREATE_SHORTCUT:                                                                
 826                 completeAddShortcut(args.intent, args.container, screenId, args.cellX,                   
 827                         args.cellY);                                                                     
 828                 break;                                                                                   
 829             case REQUEST_CREATE_APPWIDGET:                                                               
 830                 completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);            
 831                 break;                                                                                   
 832             case REQUEST_RECONFIGURE_APPWIDGET:                                                          
 833                 completeRestoreAppWidget(args.appWidgetId);                                              
 834                 break;                                                                                   
 835         }                                                                                                
 836         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,          
 837         // if you turned the screen off and then back while in All Apps, Launcher would not              
 838         // return to the workspace. Clearing mAddInfo.container here fixes this issue                    
 839         resetAddInfo();                                                                                  
 840         return screenId;                                                                                 
 841     }                                                                                                    
 842                                                                                                          
 843     private void handleActivityResult(                                                                   
 844             final int requestCode, final int resultCode, final Intent data) {                            
 845         // Reset the startActivity waiting flag                                                          
 846         setWaitingForResult(false);                                                                      
 847         final int pendingAddWidgetId = mPendingAddWidgetId;                                              
 848         mPendingAddWidgetId = -1;                                                                        
 849                                                                                                          
 850         Runnable exitSpringLoaded = new Runnable() {                                                     
 851             @Override                                                                                    
 852             public void run() {                                                                          
 853                 exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                         
 854                         EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                     
 855             }                                                                                            
 856         };                                                                                               
 857                                                                                                          
 858         if (requestCode == REQUEST_BIND_APPWIDGET) {                                                     
 859             final int appWidgetId = data != null ?                                                       
 860                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                      
 861             if (resultCode == RESULT_CANCELED) {                                                         
 862                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                
 863                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 864                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 865             } else if (resultCode == RESULT_OK) {                                                        
 866                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                     
 867                         mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                      
 868             }                                                                                            
 869             return;                                                                                      
 870         } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                              
 871             if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                              
 872                 mWorkspace.exitOverviewMode(false);                                                      
 873             }                                                                                            
 874             return;                                                                                      
 875         }                                                                                                
 876                                                                                                          
 877         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                 
 878                 requestCode == REQUEST_CREATE_APPWIDGET);                                                
 879                                                                                                          
 880         final boolean workspaceLocked = isWorkspaceLocked();                                             
 881         // We have special handling for widgets                                                          
 882         if (isWidgetDrop) {                                                                              
 883             final int appWidgetId;                                                                       
 884             int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)      
 885                     : -1;                                                                                
 886             if (widgetId < 0) {                                                                          
 887                 appWidgetId = pendingAddWidgetId;                                                        
 888             } else {                                                                                     
 889                 appWidgetId = widgetId;                                                                  
 890             }                                                                                            
 891                                                                                                          
 892             final int result;                                                                            
 893             if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                      
 894                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                          
 895                         "returned from the widget configuration activity.");                             
 896                 result = RESULT_CANCELED;                                                                
 897                 completeTwoStageWidgetDrop(result, appWidgetId);                                         
 898                 final Runnable onComplete = new Runnable() {                                             
 899                     @Override                                                                            
 900                     public void run() {                                                                  
 901                         exitSpringLoadedDragModeDelayed(false, 0, null);                                 
 902                     }                                                                                    
 903                 };                                                                                       
 904                 if (workspaceLocked) {                                                                   
 905                     // No need to remove the empty screen if we're mid-binding, as the                   
 906                     // the bind will not add the empty screen.                                           
 907                     mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);              
 908                 } else {                                                                                 
 909                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 910                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 911                 }                                                                                        
 912             } else {                                                                                     
 913                 if (!workspaceLocked) {                                                                  
 914                     if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {     
 915                         // When the screen id represents an actual screen (as opposed to a rank)         
 916                         // we make sure that the drop page actually exists.                              
 917                         mPendingAddInfo.screenId =                                                       
 918                                 ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                 
 919                     }                                                                                    
 920                     final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);  
 921                                                                                                          
 922                     dropLayout.setDropPending(true);                                                     
 923                     final Runnable onComplete = new Runnable() {                                         
 924                         @Override                                                                        
 925                         public void run() {                                                              
 926                             completeTwoStageWidgetDrop(resultCode, appWidgetId);                         
 927                             dropLayout.setDropPending(false);                                            
 928                         }                                                                                
 929                     };                                                                                   
 930                     mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                           
 931                             ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                  
 932                 } else {                                                                                 
 933                     PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,     
 934                             mPendingAddInfo);                                                            
 935                     sPendingAddItem = args;                                                              
 936                 }                                                                                        
 937             }                                                                                            
 938             return;                                                                                      
 939         }                                                                                                
 940                                                                                                          
 941         if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                              
 942             if (resultCode == RESULT_OK) {                                                               
 943                 // Update the widget view.                                                               
 944                 PendingAddArguments args = preparePendingAddArgs(requestCode, data,                      
 945                         pendingAddWidgetId, mPendingAddInfo);                                            
 946                 if (workspaceLocked) {                                                                   
 947                     sPendingAddItem = args;                                                              
 948                 } else {                                                                                 
 949                     completeAdd(args);                                                                   
 950                 }                                                                                        
 951             }                                                                                            
 952             // Leave the widget in the pending state if the user canceled the configure.                 
 953             return;                                                                                      
 954         }                                                                                                
 955                                                                                                          
 956         // The pattern used here is that a user PICKs a specific application,                            
 957         // which, depending on the target, might need to CREATE the actual target.                       
 958                                                                                                          
 959         // For example, the user would PICK_SHORTCUT for "Music playlist", and we                        
 960         // launch over to the Music app to actually CREATE_SHORTCUT.                                     
 961         if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                    
 962             final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                
 963                     mPendingAddInfo);                                                                    
 964             if (isWorkspaceLocked()) {                                                                   
 965                 sPendingAddItem = args;                                                                  
 966             } else {                                                                                     
 967                 completeAdd(args);                                                                       
 968                 mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                         
 969                         ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                      
 970             }                                                                                            
 971         } else if (resultCode == RESULT_CANCELED) {                                                      
 972             mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                             
 973                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                          
 974         }                                                                                                
 975         mDragLayer.clearAnimatedView();                                                                  
 976                                                                                                          
 977     }                                                                                                    
 978                                                                                                          
 979     @Override                                                                                            
 980     protected void onActivityResult(                                                                     
 981             final int requestCode, final int resultCode, final Intent data) {                            
 982         handleActivityResult(requestCode, resultCode, data);                                             
 983         if (mLauncherCallbacks != null) {                                                                
 984             mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                          
 985         }                                                                                                
 986     }                                                                                                    
 987                                                                                                          
 988     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                  
 989             appWidgetId, ItemInfo info) {                                                                
 990         PendingAddArguments args = new PendingAddArguments();                                            
 991         args.requestCode = requestCode;                                                                  
 992         args.intent = data;                                                                              
 993         args.container = info.container;                                                                 
 994         args.screenId = info.screenId;                                                                   
 995         args.cellX = info.cellX;                                                                         
 996         args.cellY = info.cellY;                                                                         
 997         args.appWidgetId = appWidgetId;                                                                  
 998         return args;                                                                                     
 999     }                                                                                                    
1000                                                                                                          
1001     /**                                                                                                  
1002      * Check to see if a given screen id exists. If not, create it at the end, return the new id.        
1003      *                                                                                                   
1004      * @param screenId the screen id to check                                                            
1005      * @return the new screen, or screenId if it exists                                                  
1006      */                                                                                                  
1007     private long ensurePendingDropLayoutExists(long screenId) {                                          
1008         CellLayout dropLayout =                                                                          
1009                 (CellLayout) mWorkspace.getScreenWithId(screenId);                                       
1010         if (dropLayout == null) {                                                                        
1011             // it's possible that the add screen was removed because it was                              
1012             // empty and a re-bind occurred                                                              
1013             mWorkspace.addExtraEmptyScreen();                                                            
1014             return mWorkspace.commitExtraEmptyScreen();                                                  
1015         } else {                                                                                         
1016             return screenId;                                                                             
1017         }                                                                                                
1018     }                                                                                                    
1019                                                                                                          
1020     @Thunk                                                                                               
1021     void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                       
1022         CellLayout cellLayout = ((CellLayout) (mWorkspace.getScreenWithId(mPendingAddInfo.screenId)));   
1023         Runnable onCompleteRunnable = null;                                                              
1024         int animationType = 0;                                                                           
1025         AppWidgetHostView boundWidget = null;                                                            
1026         if (resultCode == RESULT_OK) {                                                                   
1027             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                          
1028             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId, mPendingAddWidg🔵
1029             boundWidget = layout;                                                                        
1030             onCompleteRunnable = new Runnable() {                                                        
1031                 @Override                                                                                
1032                 public void run() {                                                                      
1033                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container, mPendingAddInfo.screenId🔵
1034                     exitSpringLoadedDragModeDelayed(resultCode != RESULT_CANCELED, EXIT_SPRINGLOADED_MODE🔵
1035                 }                                                                                        
1036             };                                                                                           
1037         } else if (resultCode == RESULT_CANCELED) {                                                      
1038             mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                               
1039             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                            
1040         }                                                                                                
1041         if (mDragLayer.getAnimatedView() != null) {                                                      
1042             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout, ((DragView) (mDragLayer.getAnimated🔵
1043         } else if (onCompleteRunnable != null) {                                                         
1044             // The animated view may be null in the case of a rotation during widget configuration       
1045             onCompleteRunnable.run();                                                                    
1046         }                                                                                                
1047     }                                                                                                    
1048                                                                                                          
1049     @Override                                                                                            
1050     protected void onStop() {                                                                            
1051         super.onStop();                                                                                  
1052         FirstFrameAnimatorHelper.setIsVisible(false);                                                    
1053                                                                                                          
1054         if (mLauncherCallbacks != null) {                                                                
1055             mLauncherCallbacks.onStop();                                                                 
1056         }                                                                                                
1057     }                                                                                                    
1058                                                                                                          
1059     @Override                                                                                            
1060     protected void onStart() {                                                                           
1061         super.onStart();                                                                                 
1062         FirstFrameAnimatorHelper.setIsVisible(true);                                                     
1063                                                                                                          
1064         if (mLauncherCallbacks != null) {                                                                
1065             mLauncherCallbacks.onStart();                                                                
1066         }                                                                                                
1067     }                                                                                                    
1068                                                                                                          
1069     @Override                                                                                            
1070     protected void onResume() {                                                                          
1071         long startTime = 0;                                                                              
1072         if (DEBUG_RESUME_TIME) {                                                                         
1073             startTime = System.currentTimeMillis();                                                      
1074             Log.v(TAG, "Launcher.onResume()");                                                           
1075         }                                                                                                
1076         if (mLauncherCallbacks != null) {                                                                
1077             mLauncherCallbacks.preOnResume();                                                            
1078         }                                                                                                
1079         super.onResume();                                                                                
1080         // Restore the previous launcher state                                                           
1081         if (mOnResumeState == State.WORKSPACE) {                                                         
1082             showWorkspace(false);                                                                        
1083         } else if (mOnResumeState == State.APPS) {                                                       
1084             /* animated */                                                                               
1085             /* resetListToTop */                                                                         
1086             showAppsView(false, false);                                                                  
1087         } else if (mOnResumeState == State.WIDGETS) {                                                    
1088             showWidgetsView(false, false);                                                               
1089         }                                                                                                
1090         mOnResumeState = State.NONE;                                                                     
1091         // Background was set to gradient in onPause(), restore to black if in all apps.                 
1092         setWorkspaceBackground(mState == State.WORKSPACE);                                               
1093         mPaused = false;                                                                                 
1094         if (mRestoring || mOnResumeNeedsLoad) {                                                          
1095             setWorkspaceLoading(true);                                                                   
1096             mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                    
1097             mRestoring = false;                                                                          
1098             mOnResumeNeedsLoad = false;                                                                  
1099         }                                                                                                
1100         if (mBindOnResumeCallbacks.size() > 0) {                                                         
1101             // We might have postponed some bind calls until onResume (see waitUntilResume) --           
1102             // execute them here                                                                         
1103             long startTimeCallbacks = 0;                                                                 
1104             if (DEBUG_RESUME_TIME) {                                                                     
1105                 startTimeCallbacks = System.currentTimeMillis();                                         
1106             }                                                                                            
1107             for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                    
1108                 mBindOnResumeCallbacks.get(i).run();                                                     
1109             }                                                                                            
1110             mBindOnResumeCallbacks.clear();                                                              
1111             if (DEBUG_RESUME_TIME) {                                                                     
1112                 Log.d(TAG, "Time spent processing callbacks in onResume: " + (System.currentTimeMillis() 🔵
1113             }                                                                                            
1114         }                                                                                                
1115         if (mOnResumeCallbacks.size() > 0) {                                                             
1116             for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                        
1117                 mOnResumeCallbacks.get(i).run();                                                         
1118             }                                                                                            
1119             mOnResumeCallbacks.clear();                                                                  
1120         }                                                                                                
1121         // Reset the pressed state of icons that were locked in the press state while activities         
1122         // were launching                                                                                
1123         if (mWaitingForResume != null) {                                                                 
1124             // Resets the previous workspace icon press state                                            
1125             mWaitingForResume.setStayPressed(false);                                                     
1126         }                                                                                                
1127         // It is possible that widgets can receive updates while launcher is not in the foreground.      
1128         // Consequently, the widgets will be inflated in the orientation of the foreground activity      
1129         // (framework issue). On resuming, we ensure that any widgets are inflated for the current       
1130         // orientation.                                                                                  
1131         getWorkspace().reinflateWidgetsIfNecessary();                                                    
1132         reinflateQSBIfNecessary();                                                                       
1133         // Process any items that were added while Launcher was away.                                    
1134         InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                       
1135         if (DEBUG_RESUME_TIME) {                                                                         
1136             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));           
1137         }                                                                                                
1138         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1139             // If we are resuming and the custom content is the current page, we call onShow().          
1140             // It is also poassible that onShow will instead be called slightly after first layout       
1141             // if PagedView#setRestorePage was set to the custom content page in onCreate().             
1142             if (mWorkspace.isOnOrMovingToCustomContent()) {                                              
1143                 mWorkspace.getCustomContentCallbacks().onShow(true);                                     
1144             }                                                                                            
1145         }                                                                                                
1146         mWorkspace.updateInteractionForState();                                                          
1147         mWorkspace.onResume();                                                                           
1148         PackageInstallerCompat.getInstance(this).onResume();                                             
1149         if (mLauncherCallbacks != null) {                                                                
1150             mLauncherCallbacks.onResume();                                                               
1151         }                                                                                                
1152     }                                                                                                    
1153                                                                                                          
1154     @Override                                                                                            
1155     protected void onPause() {                                                                           
1156         // Ensure that items added to Launcher are queued until Launcher returns                         
1157         InstallShortcutReceiver.enableInstallQueue();                                                    
1158         PackageInstallerCompat.getInstance(this).onPause();                                              
1159                                                                                                          
1160         super.onPause();                                                                                 
1161         mPaused = true;                                                                                  
1162         mDragController.cancelDrag();                                                                    
1163         mDragController.resetLastGestureUpTime();                                                        
1164                                                                                                          
1165         // We call onHide() aggressively. The custom content callbacks should be able to                 
1166         // debounce excess onHide calls.                                                                 
1167         if (mWorkspace.getCustomContentCallbacks() != null) {                                            
1168             mWorkspace.getCustomContentCallbacks().onHide();                                             
1169         }                                                                                                
1170                                                                                                          
1171         if (mLauncherCallbacks != null) {                                                                
1172             mLauncherCallbacks.onPause();                                                                
1173         }                                                                                                
1174     }                                                                                                    
1175                                                                                                          
1176     public interface CustomContentCallbacks {                                                            
1177         // Custom content is completely shown. {@code fromResume} indicates whether this was caused      
1178         // by a onResume or by scrolling otherwise.                                                      
1179         public abstract void onShow(boolean fromResume);                                                 
1180                                                                                                          
1181         // Custom content is completely hidden                                                           
1182         public abstract void onHide();                                                                   
1183                                                                                                          
1184         // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).            
1185         public abstract void onScrollProgressChanged(float progress);                                    
1186                                                                                                          
1187         // Indicates whether the user is allowed to scroll away from the custom content.                 
1188         public abstract boolean isScrollingAllowed();                                                    
1189     }                                                                                                    
1190                                                                                                          
1191     public interface LauncherOverlay {                                                                   
1192         /**                                                                                              
1193          * Touch interaction leading to overscroll has begun                                             
1194          */                                                                                              
1195         public abstract void onScrollInteractionBegin();                                                 
1196                                                                                                          
1197         /**                                                                                              
1198          * Touch interaction related to overscroll has ended                                             
1199          */                                                                                              
1200         public abstract void onScrollInteractionEnd();                                                   
1201                                                                                                          
1202         /**                                                                                              
1203          * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                 
1204          * screen (or in the case of RTL, the rightmost screen).                                         
1205          */                                                                                              
1206         public abstract void onScrollChange(int progress, boolean rtl);                                  
1207                                                                                                          
1208         /**                                                                                              
1209          * Screen has stopped scrolling                                                                  
1210          */                                                                                              
1211         public abstract void onScrollSettled();                                                          
1212                                                                                                          
1213         /**                                                                                              
1214          * This method can be called by the Launcher in order to force the LauncherOverlay               
1215          * to exit fully immersive mode.                                                                 
1216          */                                                                                              
1217         public abstract void forceExitFullImmersion();                                                   
1218     }                                                                                                    
1219                                                                                                          
1220     public interface LauncherAppsCallbacks {                                                             
1221         /**                                                                                              
1222          * Updates launcher to the available space that AllApps can take so as not to overlap with       
1223          * any other views.                                                                              
1224          */                                                                                              
1225         public abstract void onAllAppsBoundsChanged(Rect bounds);                                        
1226                                                                                                          
1227         /**                                                                                              
1228          * Called to dismiss all apps if it is showing.                                                  
1229          */                                                                                              
1230         public abstract void dismissAllApps();                                                           
1231     }                                                                                                    
1232                                                                                                          
1233     public interface LauncherOverlayCallbacks {                                                          
1234         /**                                                                                              
1235          * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,           
1236          * however it doesn't modify any state within the launcher.                                      
1237          */                                                                                              
1238         public abstract boolean canEnterFullImmersion();                                                 
1239                                                                                                          
1240         /**                                                                                              
1241          * Should be called to tell Launcher that the LauncherOverlay will take over interaction,        
1242          * eg. by occupying the full screen and handling all touch events.                               
1243          *                                                                                               
1244          * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this        
1245         case, Launcher will modify any necessary state and assumes the overlay is                        
1246         handling all interaction. If false, the LauncherOverlay should cancel any                        
1247          */                                                                                              
1248         public abstract boolean enterFullImmersion();                                                    
1249                                                                                                          
1250         /**                                                                                              
1251          * Must be called when exiting fully immersive mode. Indicates to Launcher that it has           
1252          * full control over UI and state.                                                               
1253          */                                                                                              
1254         public abstract void exitFullImmersion();                                                        
1255     }                                                                                                    
1256                                                                                                          
1257     class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                             
1258         @Override                                                                                        
1259         public boolean canEnterFullImmersion() {                                                         
1260             return mState == State.WORKSPACE;                                                            
1261         }                                                                                                
1262                                                                                                          
1263         @Override                                                                                        
1264         public boolean enterFullImmersion() {                                                            
1265             if (mState == State.WORKSPACE) {                                                             
1266                 // When fully immersed, disregard any touches which fall through.                        
1267                 mDragLayer.setBlockTouch(true);                                                          
1268                 return true;                                                                             
1269             }                                                                                            
1270             return false;                                                                                
1271         }                                                                                                
1272                                                                                                          
1273         @Override                                                                                        
1274         public void exitFullImmersion() {                                                                
1275             mDragLayer.setBlockTouch(false);                                                             
1276         }                                                                                                
1277     }                                                                                                    
1278                                                                                                          
1279     protected boolean hasSettings() {                                                                    
1280         if (mLauncherCallbacks != null) {                                                                
1281             return mLauncherCallbacks.hasSettings();                                                     
1282         }                                                                                                
1283         return false;                                                                                    
1284     }                                                                                                    
1285                                                                                                          
1286     public void addToCustomContentPage(View customContent,                                               
1287             CustomContentCallbacks callbacks, String description) {                                      
1288         mWorkspace.addToCustomContentPage(customContent, callbacks, description);                        
1289     }                                                                                                    
1290                                                                                                          
1291     // The custom content needs to offset its content to account for the QSB                             
1292     public int getTopOffsetForCustomContent() {                                                          
1293         return mWorkspace.getPaddingTop();                                                               
1294     }                                                                                                    
1295                                                                                                          
1296     @Override                                                                                            
1297     public Object onRetainNonConfigurationInstance() {                                                   
1298         // Flag the loader to stop early before switching                                                
1299         if (mModel.isCurrentCallbacks(this)) {                                                           
1300             mModel.stopLoader();                                                                         
1301         }                                                                                                
1302         //TODO(hyunyoungs): stop the widgets loader when there is a rotation.                            
1303         return Boolean.TRUE;                                                                             
1304     }                                                                                                    
1305                                                                                                          
1306     // We can't hide the IME if it was forced open.  So don't bother                                     
1307     @Override                                                                                            
1308     public void onWindowFocusChanged(boolean hasFocus) {                                                 
1309         super.onWindowFocusChanged(hasFocus);                                                            
1310         mHasFocus = hasFocus;                                                                            
1311                                                                                                          
1312         if (mLauncherCallbacks != null) {                                                                
1313             mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                           
1314         }                                                                                                
1315     }                                                                                                    
1316                                                                                                          
1317     private boolean acceptFilter() {                                                                     
1318         final InputMethodManager inputManager = (InputMethodManager)                                     
1319                 getSystemService(Context.INPUT_METHOD_SERVICE);                                          
1320         return !inputManager.isFullscreenMode();                                                         
1321     }                                                                                                    
1322                                                                                                          
1323     @Override                                                                                            
1324     public boolean onKeyDown(int keyCode, KeyEvent event) {                                              
1325         final int uniChar = event.getUnicodeChar();                                                      
1326         final boolean handled = super.onKeyDown(keyCode, event);                                         
1327         final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);              
1328         if (!handled && acceptFilter() && isKeyNotWhitespace) {                                          
1329             boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,         
1330                     keyCode, event);                                                                     
1331             if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                       
1332                 // something usable has been typed - start a search                                      
1333                 // the typed text will be retrieved and cleared by                                       
1334                 // showSearchDialog()                                                                    
1335                 // If there are multiple keystrokes before the search dialog takes focus,                
1336                 // onSearchRequested() will be called for every keystroke,                               
1337                 // but it is idempotent, so it's fine.                                                   
1338                 return onSearchRequested();                                                              
1339             }                                                                                            
1340         }                                                                                                
1341                                                                                                          
1342         // Eat the long press event so the keyboard doesn't come up.                                     
1343         if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                   
1344             return true;                                                                                 
1345         }                                                                                                
1346                                                                                                          
1347         return handled;                                                                                  
1348     }                                                                                                    
1349                                                                                                          
1350     private String getTypedText() {                                                                      
1351         return mDefaultKeySsb.toString();                                                                
1352     }                                                                                                    
1353                                                                                                          
1354     private void clearTypedText() {                                                                      
1355         mDefaultKeySsb.clear();                                                                          
1356         mDefaultKeySsb.clearSpans();                                                                     
1357         Selection.setSelection(mDefaultKeySsb, 0);                                                       
1358     }                                                                                                    
1359                                                                                                          
1360     /**                                                                                                  
1361      * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type      
1362      * State                                                                                             
1363      */                                                                                                  
1364     private static State intToState(int stateOrdinal) {                                                  
1365         State state = State.WORKSPACE;                                                                   
1366         final State[] stateValues = State.values();                                                      
1367         for (int i = 0; i < stateValues.length; i++) {                                                   
1368             if (stateValues[i].ordinal() == stateOrdinal) {                                              
1369                 state = stateValues[i];                                                                  
1370                 break;                                                                                   
1371             }                                                                                            
1372         }                                                                                                
1373         return state;                                                                                    
1374     }                                                                                                    
1375                                                                                                          
1376     /**                                                                                                  
1377      * Restores the previous state, if it exists.                                                        
1378      *                                                                                                   
1379      * @param savedState The previous state.                                                             
1380      */                                                                                                  
1381     @SuppressWarnings("unchecked")                                                                       
1382     private void restoreState(Bundle savedState) {                                                       
1383         if (savedState == null) {                                                                        
1384             return;                                                                                      
1385         }                                                                                                
1386         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));           
1387         if ((state == State.APPS) || (state == State.WIDGETS)) {                                         
1388             mOnResumeState = state;                                                                      
1389         }                                                                                                
1390         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, PagedView.INVALID_RESTORE_PAG🔵
1391         if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                           
1392             mWorkspace.setRestorePage(currentScreen);                                                    
1393         }                                                                                                
1394         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);    
1395         final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);          
1396         if ((pendingAddContainer != ItemInfo.NO_ID) && (pendingAddScreen > (-1))) {                      
1397             mPendingAddInfo.container = pendingAddContainer;                                             
1398             mPendingAddInfo.screenId = pendingAddScreen;                                                 
1399             mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                 
1400             mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                 
1401             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                 
1402             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                 
1403             AppWidgetProviderInfo info = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);
1404             mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this, info);          
1405             mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                
1406             setWaitingForResult(true);                                                                   
1407             mRestoring = true;                                                                           
1408         }                                                                                                
1409         boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);        
1410         if (renameFolder) {                                                                              
1411             long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                        
1412             mFolderInfo = mModel.getFolderById(this, sFolders, id);                                      
1413             mRestoring = true;                                                                           
1414         }                                                                                                
1415         mItemIdToViewId = ((HashMap<Integer, Integer>) (savedState.getSerializable(RUNTIME_STATE_VIEW_IDS🔵
1416     }                                                                                                    
1417                                                                                                          
1418     /**                                                                                                  
1419      * Finds all the views we need and configure them properly.                                          
1420      */                                                                                                  
1421     private void setupViews() {                                                                          
1422         final DragController dragController = mDragController;                                           
1423         mLauncherView = findViewById(R.id.launcher);                                                     
1424         mFocusHandler = ((FocusIndicatorView) (findViewById(R.id.focus_indicator)));                     
1425         mDragLayer = ((DragLayer) (findViewById(R.id.drag_layer)));                                      
1426         mWorkspace = ((Workspace) (mDragLayer.findViewById(R.id.workspace)));                            
1427         mWorkspace.setPageSwitchListener(this);                                                          
1428         mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                  
1429         mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_L🔵
1430         mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);              
1431         // Setup the drag layer                                                                          
1432         mDragLayer.setup(this, dragController);                                                          
1433         // Setup the hotseat                                                                             
1434         mHotseat = ((Hotseat) (findViewById(R.id.hotseat)));                                             
1435         if (mHotseat != null) {                                                                          
1436             mHotseat.setup(this);                                                                        
1437             mHotseat.setOnLongClickListener(this);                                                       
1438         }                                                                                                
1439         mOverviewPanel = ((ViewGroup) (findViewById(R.id.overview_panel)));                              
1440         View widgetButton = findViewById(R.id.widget_button);                                            
1441         widgetButton.setOnClickListener(new OnClickListener() {                                          
1442             @Override                                                                                    
1443             public void onClick(View arg0) {                                                             
1444                 if (!mWorkspace.isSwitchingState()) {                                                    
1445                     onClickAddWidgetButton(arg0);                                                        
1446                 }                                                                                        
1447             }                                                                                            
1448         });                                                                                              
1449         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                               
1450         View wallpaperButton = findViewById(R.id.wallpaper_button);                                      
1451         wallpaperButton.setOnClickListener(new OnClickListener() {                                       
1452             @Override                                                                                    
1453             public void onClick(View arg0) {                                                             
1454                 if (!mWorkspace.isSwitchingState()) {                                                    
1455                     onClickWallpaperPicker(arg0);                                                        
1456                 }                                                                                        
1457             }                                                                                            
1458         });                                                                                              
1459         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                            
1460         View settingsButton = findViewById(R.id.settings_button);                                        
1461         if (hasSettings()) {                                                                             
1462             settingsButton.setOnClickListener(new OnClickListener() {                                    
1463                 @Override                                                                                
1464                 public void onClick(View arg0) {                                                         
1465                     if (!mWorkspace.isSwitchingState()) {                                                
1466                         onClickSettingsButton(arg0);                                                     
1467                     }                                                                                    
1468                 }                                                                                        
1469             });                                                                                          
1470             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                         
1471         } else {                                                                                         
1472             settingsButton.setVisibility(View.GONE);                                                     
1473         }                                                                                                
1474         mOverviewPanel.setAlpha(0.0F);                                                                   
1475         // Setup the workspace                                                                           
1476         mWorkspace.setHapticFeedbackEnabled(false);                                                      
1477         mWorkspace.setOnLongClickListener(this);                                                         
1478         mWorkspace.setup(dragController);                                                                
1479         dragController.addDragListener(mWorkspace);                                                      
1480         // Get the search/delete bar                                                                     
1481         mSearchDropTargetBar = ((SearchDropTargetBar) (mDragLayer.findViewById(R.id.search_drop_target_ba🔵
1482         // Setup Apps                                                                                    
1483         mAppsView = ((AppsContainerView) (findViewById(R.id.apps_view)));                                
1484         if ((mLauncherCallbacks != null) && mLauncherCallbacks.overrideAllAppsSearch()) {                
1485             mAppsView.hideSearchBar();                                                                   
1486         }                                                                                                
1487         // Setup AppsCustomize                                                                           
1488         mWidgetsView = ((WidgetsContainerView) (findViewById(R.id.widgets_view)));                       
1489         // Setup the drag controller (drop targets have to be added in reverse order in priority)        
1490         dragController.setDragScoller(mWorkspace);                                                       
1491         dragController.setScrollView(mDragLayer);                                                        
1492         dragController.setMoveTarget(mWorkspace);                                                        
1493         dragController.addDropTarget(mWorkspace);                                                        
1494         if (mSearchDropTargetBar != null) {                                                              
1495             mSearchDropTargetBar.setup(this, dragController);                                            
1496             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
1497         }                                                                                                
1498         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                    
1499             Log.v(TAG, "adding WeightWatcher");                                                          
1500             mWeightWatcher = new WeightWatcher(this);                                                    
1501             mWeightWatcher.setAlpha(0.5F);                                                               
1502             ((FrameLayout) (mLauncherView)).addView(mWeightWatcher, new FrameLayout.LayoutParams(FrameLay🔵
1503             boolean show = shouldShowWeightWatcher();                                                    
1504             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
1505         }                                                                                                
1506     }                                                                                                    
1507                                                                                                          
1508     /**                                                                                                  
1509      * Sets the all apps button. This method is called from {@link Hotseat}.                             
1510      */                                                                                                  
1511     public void setAllAppsButton(View allAppsButton) {                                                   
1512         mAllAppsButton = allAppsButton;                                                                  
1513     }                                                                                                    
1514                                                                                                          
1515     public View getAllAppsButton() {                                                                     
1516         return mAllAppsButton;                                                                           
1517     }                                                                                                    
1518                                                                                                          
1519     /**                                                                                                  
1520      * Creates a view representing a shortcut.                                                           
1521      *                                                                                                   
1522      * @param info The data structure describing the shortcut.                                           
1523      *                                                                                                   
1524      * @return A View inflated from R.layout.application.                                                
1525      */                                                                                                  
1526     View createShortcut(ShortcutInfo info) {                                                             
1527         return createShortcut(R.layout.application,                                                      
1528                 (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                   
1529     }                                                                                                    
1530                                                                                                          
1531     /**                                                                                                  
1532      * Creates a view representing a shortcut inflated from the specified resource.                      
1533      *                                                                                                   
1534      * @param layoutResId The id of the XML layout used to create the shortcut.                          
1535      * @param parent The group the shortcut belongs to.                                                  
1536      * @param info The data structure describing the shortcut.                                           
1537      *                                                                                                   
1538      * @return A View inflated from layoutResId.                                                         
1539      */                                                                                                  
1540     public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                   
1541         BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);        
1542         favorite.applyFromShortcutInfo(info, mIconCache, true);                                          
1543         favorite.setOnClickListener(this);                                                               
1544         favorite.setOnFocusChangeListener(mFocusHandler);                                                
1545         return favorite;                                                                                 
1546     }                                                                                                    
1547                                                                                                          
1548     /**                                                                                                  
1549      * Add a shortcut to the workspace.                                                                  
1550      *                                                                                                   
1551      * @param data The intent describing the shortcut.                                                   
1552      * @param cellInfo The position on screen where to create the shortcut.                              
1553      */                                                                                                  
1554     private void completeAddShortcut(Intent data, long container, long screenId, int cellX, int cellY) { 
1555         int[] cellXY = mTmpAddItemCellCoordinates;                                                       
1556         int[] touchXY = mPendingAddInfo.dropPos;                                                         
1557         CellLayout layout = getCellLayout(container, screenId);                                          
1558         boolean foundCellSpan = false;                                                                   
1559         ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                   
1560         if (info == null) {                                                                              
1561             return;                                                                                      
1562         }                                                                                                
1563         final View view = createShortcut(info);                                                          
1564         // First we check if we already know the exact location where we want to add this item.          
1565         if ((cellX >= 0) && (cellY >= 0)) {                                                              
1566             cellXY[0] = cellX;                                                                           
1567             cellXY[1] = cellY;                                                                           
1568             foundCellSpan = true;                                                                        
1569             // If appropriate, either create a folder or add to an existing folder                       
1570             if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0, true, null, nu🔵
1571                 return;                                                                                  
1572             }                                                                                            
1573             DragObject dragObject = new DragObject();                                                    
1574             dragObject.dragInfo = info;                                                                  
1575             if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject, true)) {  
1576                 return;                                                                                  
1577             }                                                                                            
1578         } else if (touchXY != null) {                                                                    
1579             // when dragging and dropping, just find the closest free spot                               
1580             int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);           
1581             foundCellSpan = result != null;                                                              
1582         } else {                                                                                         
1583             foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                        
1584         }                                                                                                
1585         if (!foundCellSpan) {                                                                            
1586             showOutOfSpaceMessage(isHotseatLayout(layout));                                              
1587             return;                                                                                      
1588         }                                                                                                
1589         LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1]);          
1590         if (!mRestoring) {                                                                               
1591             mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1, isWorkspaceLock🔵
1592         }                                                                                                
1593     }                                                                                                    
1594                                                                                                          
1595     static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                
1596             int minHeight) {                                                                             
1597         Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);           
1598         // We want to account for the extra amount of padding that we are adding to the widget           
1599         // to ensure that it gets the full amount of space that it has requested                         
1600         int requiredWidth = minWidth + padding.left + padding.right;                                     
1601         int requiredHeight = minHeight + padding.top + padding.bottom;                                   
1602         return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                               
1603     }                                                                                                    
1604                                                                                                          
1605     static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                         
1606         return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                  
1607     }                                                                                                    
1608                                                                                                          
1609     static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                      
1610         return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);      
1611     }                                                                                                    
1612                                                                                                          
1613     static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                          
1614         return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);             
1615     }                                                                                                    
1616                                                                                                          
1617     static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                       
1618         return getSpanForWidget(context, info.componentName, info.minResizeWidth, info.minResizeHeight); 
1619     }                                                                                                    
1620                                                                                                          
1621     /**                                                                                                  
1622      * Add a widget to the workspace.                                                                    
1623      *                                                                                                   
1624      * @param appWidgetId The app widget id                                                              
1625      */                                                                                                  
1626     @Thunk                                                                                               
1627     void completeAddAppWidget(int appWidgetId, long container, long screenId, AppWidgetHostView hostView,🔵
1628         ItemInfo info = mPendingAddInfo;                                                                 
1629         if (appWidgetInfo == null) {                                                                     
1630             appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this, mAppWidgetManager.getApp🔵
1631         }                                                                                                
1632         if (appWidgetInfo.isCustomWidget) {                                                              
1633             appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                        
1634         }                                                                                                
1635         LauncherAppWidgetInfo launcherInfo;                                                              
1636         launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                   
1637         launcherInfo.spanX = info.spanX;                                                                 
1638         launcherInfo.spanY = info.spanY;                                                                 
1639         launcherInfo.minSpanX = info.minSpanX;                                                           
1640         launcherInfo.minSpanY = info.minSpanY;                                                           
1641         launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                    
1642         LauncherModel.addItemToDatabase(this, launcherInfo, container, screenId, info.cellX, info.cellY);
1643         if (!mRestoring) {                                                                               
1644             if (hostView == null) {                                                                      
1645                 // Perform actual inflation because we're live                                           
1646                 launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);     
1647             } else {                                                                                     
1648                 // The AppWidgetHostView has already been inflated and instantiated                      
1649                 launcherInfo.hostView = hostView;                                                        
1650             }                                                                                            
1651             launcherInfo.hostView.setTag(launcherInfo);                                                  
1652             launcherInfo.hostView.setVisibility(View.VISIBLE);                                           
1653             launcherInfo.notifyWidgetSizeChanged(this);                                                  
1654             mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX, info.cellY, la🔵
1655             addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                        
1656         }                                                                                                
1657         resetAddInfo();                                                                                  
1658     }                                                                                                    
1659                                                                                                          
1660     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                
1661         @Override                                                                                        
1662         public void onReceive(Context context, Intent intent) {                                          
1663             final String action = intent.getAction();                                                    
1664             if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                               
1665                 mUserPresent = false;                                                                    
1666                 mDragLayer.clearAllResizeFrames();                                                       
1667                 updateAutoAdvanceState();                                                                
1668                 // Reset AllApps to its initial state only if we are not in the middle of                
1669                 // processing a multi-step drop                                                          
1670                 if (((mAppsView != null) && (mWidgetsView != null)) && (mPendingAddInfo.container == Item🔵
1671                     showWorkspace(false);                                                                
1672                 }                                                                                        
1673             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                      
1674                 mUserPresent = true;                                                                     
1675                 updateAutoAdvanceState();                                                                
1676             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {            
1677                 mModel.resetLoadedState(false, true);                                                    
1678                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR🔵
1679             } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {           
1680                 mModel.resetLoadedState(false, true);                                                    
1681                 mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE, LauncherModel.LOADER_FLAG_CLEAR🔵
1682             } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action) || LauncherAppsComp🔵
1683                 getModel().forceReload();                                                                
1684             }                                                                                            
1685         }                                                                                                
1686     };                                                                                                   
1687                                                                                                          
1688     @Override                                                                                            
1689     public void onAttachedToWindow() {                                                                   
1690         super.onAttachedToWindow();                                                                      
1691                                                                                                          
1692         // Listen for broadcasts related to user-presence                                                
1693         final IntentFilter filter = new IntentFilter();                                                  
1694         filter.addAction(Intent.ACTION_SCREEN_OFF);                                                      
1695         filter.addAction(Intent.ACTION_USER_PRESENT);                                                    
1696         // For handling managed profiles                                                                 
1697         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                               
1698         filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                             
1699         if (ENABLE_DEBUG_INTENTS) {                                                                      
1700             filter.addAction(DebugIntents.DELETE_DATABASE);                                              
1701             filter.addAction(DebugIntents.MIGRATE_DATABASE);                                             
1702         }                                                                                                
1703         registerReceiver(mReceiver, filter);                                                             
1704         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                     
1705         setupTransparentSystemBarsForLmp();                                                              
1706         mAttached = true;                                                                                
1707         mVisible = true;                                                                                 
1708     }                                                                                                    
1709                                                                                                          
1710     /**                                                                                                  
1711      * Sets up transparent navigation and status bars in LMP.                                            
1712      * This method is a no-op for other platform versions.                                               
1713      */                                                                                                  
1714     @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                             
1715     private void setupTransparentSystemBarsForLmp() {                                                    
1716         if (Utilities.isLmpOrAbove()) {                                                                  
1717             Window window = getWindow();                                                                 
1718             window.getAttributes().systemUiVisibility |= (View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM🔵
1719             window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutPa🔵
1720             window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);               
1721             window.setStatusBarColor(Color.TRANSPARENT);                                                 
1722             window.setNavigationBarColor(Color.TRANSPARENT);                                             
1723         }                                                                                                
1724     }                                                                                                    
1725                                                                                                          
1726     @Override                                                                                            
1727     public void onDetachedFromWindow() {                                                                 
1728         super.onDetachedFromWindow();                                                                    
1729         mVisible = false;                                                                                
1730         if (mAttached) {                                                                                 
1731             unregisterReceiver(mReceiver);                                                               
1732             mAttached = false;                                                                           
1733         }                                                                                                
1734         updateAutoAdvanceState();                                                                        
1735     }                                                                                                    
1736                                                                                                          
1737     public void onWindowVisibilityChanged(int visibility) {                                              
1738         mVisible = visibility == View.VISIBLE;                                                           
1739         updateAutoAdvanceState();                                                                        
1740         // The following code used to be in onResume, but it turns out onResume is called when           
1741         // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged           
1742         // is a more appropriate event to handle                                                         
1743         if (mVisible) {                                                                                  
1744             if (!mWorkspaceLoading) {                                                                    
1745                 final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                      
1746                 // We want to let Launcher draw itself at least once before we force it to build         
1747                 // layers on all the workspace pages, so that transitioning to Launcher from other       
1748                 // apps is nice and speedy.                                                              
1749                 observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                       
1750                     private boolean mStarted = false;                                                    
1751                                                                                                          
1752                     public void onDraw() {                                                               
1753                         if (mStarted) {                                                                  
1754                             return;                                                                      
1755                         }                                                                                
1756                         mStarted = true;                                                                 
1757                         // We delay the layer building a bit in order to give                            
1758                         // other message processing a time to run.  In particular                        
1759                         // this avoids a delay in hiding the IME if it was                               
1760                         // currently shown, because doing that may involve                               
1761                         // some communication back with the app.                                         
1762                         mWorkspace.postDelayed(mBuildLayersRunnable, 500);                               
1763                         final ViewTreeObserver.OnDrawListener listener = this;                           
1764                         mWorkspace.post(new Runnable() {                                                 
1765                             public void run() {                                                          
1766                                 if ((mWorkspace != null) && (mWorkspace.getViewTreeObserver() != null)) {
1767                                     mWorkspace.getViewTreeObserver().removeOnDrawListener(listener);     
1768                                 }                                                                        
1769                             }                                                                            
1770                         });                                                                              
1771                         return;                                                                          
1772                     }                                                                                    
1773                 });                                                                                      
1774             }                                                                                            
1775             clearTypedText();                                                                            
1776         }                                                                                                
1777     }                                                                                                    
1778                                                                                                          
1779     @Thunk                                                                                               
1780     void sendAdvanceMessage(long delay) {                                                                
1781         mHandler.removeMessages(ADVANCE_MSG);                                                            
1782         Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                               
1783         mHandler.sendMessageDelayed(msg, delay);                                                         
1784         mAutoAdvanceSentTime = System.currentTimeMillis();                                               
1785     }                                                                                                    
1786                                                                                                          
1787     @Thunk                                                                                               
1788     void updateAutoAdvanceState() {                                                                      
1789         boolean autoAdvanceRunning = (mVisible && mUserPresent) && (!mWidgetsToAdvance.isEmpty());       
1790         if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                 
1791             mAutoAdvanceRunning = autoAdvanceRunning;                                                    
1792             if (autoAdvanceRunning) {                                                                    
1793                 long delay = (mAutoAdvanceTimeLeft == (-1)) ? mAdvanceInterval : mAutoAdvanceTimeLeft;   
1794                 sendAdvanceMessage(delay);                                                               
1795             } else {                                                                                     
1796                 if (!mWidgetsToAdvance.isEmpty()) {                                                      
1797                     mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval - (System.currentTimeMillis() - m🔵
1798                 }                                                                                        
1799                 mHandler.removeMessages(ADVANCE_MSG);                                                    
1800                 mHandler.removeMessages(0);// Remove messages sent using postDelayed()                   
1801                                                                                                          
1802             }                                                                                            
1803         }                                                                                                
1804     }                                                                                                    
1805                                                                                                          
1806     private final Handler mHandler = new Handler() {                                                     
1807         @Override                                                                                        
1808         public void handleMessage(Message msg) {                                                         
1809             if (msg.what == ADVANCE_MSG) {                                                               
1810                 int i = 0;                                                                               
1811                 for (View key: mWidgetsToAdvance.keySet()) {                                             
1812                     final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);       
1813                     final int delay = mAdvanceStagger * i;                                               
1814                     if (v instanceof Advanceable) {                                                      
1815                        postDelayed(new Runnable() {                                                      
1816                            public void run() {                                                           
1817                                ((Advanceable) v).advance();                                              
1818                            }                                                                             
1819                        }, delay);                                                                        
1820                     }                                                                                    
1821                     i++;                                                                                 
1822                 }                                                                                        
1823                 sendAdvanceMessage(mAdvanceInterval);                                                    
1824             }                                                                                            
1825         }                                                                                                
1826     };                                                                                                   
1827                                                                                                          
1828     void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {            
1829         if ((appWidgetInfo == null) || (appWidgetInfo.autoAdvanceViewId == (-1))) {                      
1830             return;                                                                                      
1831         }                                                                                                
1832         View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                 
1833         if (v instanceof Advanceable) {                                                                  
1834             mWidgetsToAdvance.put(hostView, appWidgetInfo);                                              
1835             ((Advanceable) (v)).fyiWillBeAdvancedByHostKThx();                                           
1836             updateAutoAdvanceState();                                                                    
1837         }                                                                                                
1838     }                                                                                                    
1839                                                                                                          
1840     void removeWidgetToAutoAdvance(View hostView) {                                                      
1841         if (mWidgetsToAdvance.containsKey(hostView)) {                                                   
1842             mWidgetsToAdvance.remove(hostView);                                                          
1843             updateAutoAdvanceState();                                                                    
1844         }                                                                                                
1845     }                                                                                                    
1846                                                                                                          
1847     public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                    
1848         removeWidgetToAutoAdvance(launcherInfo.hostView);                                                
1849         launcherInfo.hostView = null;                                                                    
1850     }                                                                                                    
1851                                                                                                          
1852     public void showOutOfSpaceMessage(boolean isHotseatLayout) {                                         
1853         int strId = (isHotseatLayout) ? R.string.hotseat_out_of_space : R.string.out_of_space;           
1854         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                               
1855     }                                                                                                    
1856                                                                                                          
1857     public DragLayer getDragLayer() {                                                                    
1858         return mDragLayer;                                                                               
1859     }                                                                                                    
1860                                                                                                          
1861     public AppsContainerView getAppsView() {                                                             
1862         return mAppsView;                                                                                
1863     }                                                                                                    
1864                                                                                                          
1865     public WidgetsContainerView getWidgetsView() {                                                       
1866         return mWidgetsView;                                                                             
1867     }                                                                                                    
1868                                                                                                          
1869     public Workspace getWorkspace() {                                                                    
1870         return mWorkspace;                                                                               
1871     }                                                                                                    
1872                                                                                                          
1873     public Hotseat getHotseat() {                                                                        
1874         return mHotseat;                                                                                 
1875     }                                                                                                    
1876                                                                                                          
1877     public ViewGroup getOverviewPanel() {                                                                
1878         return mOverviewPanel;                                                                           
1879     }                                                                                                    
1880                                                                                                          
1881     public SearchDropTargetBar getSearchBar() {                                                          
1882         return mSearchDropTargetBar;                                                                     
1883     }                                                                                                    
1884                                                                                                          
1885     public LauncherAppWidgetHost getAppWidgetHost() {                                                    
1886         return mAppWidgetHost;                                                                           
1887     }                                                                                                    
1888                                                                                                          
1889     public LauncherModel getModel() {                                                                    
1890         return mModel;                                                                                   
1891     }                                                                                                    
1892                                                                                                          
1893     protected SharedPreferences getSharedPrefs() {                                                       
1894         return mSharedPrefs;                                                                             
1895     }                                                                                                    
1896                                                                                                          
1897     public void closeSystemDialogs() {                                                                   
1898         getWindow().closeAllPanels();                                                                    
1899                                                                                                          
1900         // Whatever we were doing is hereby canceled.                                                    
1901         setWaitingForResult(false);                                                                      
1902     }                                                                                                    
1903                                                                                                          
1904     @Override                                                                                            
1905     protected void onNewIntent(Intent intent) {                                                          
1906         long startTime = 0;                                                                              
1907         if (DEBUG_RESUME_TIME) {                                                                         
1908             startTime = System.currentTimeMillis();                                                      
1909         }                                                                                                
1910         super.onNewIntent(intent);                                                                       
1911         // Close the menu                                                                                
1912         if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                             
1913             // also will cancel mWaitingForResult.                                                       
1914             closeSystemDialogs();                                                                        
1915             final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT🔵
1916             if (mWorkspace == null) {                                                                    
1917                 // Can be cases where mWorkspace is null, this prevents a NPE                            
1918                 return;                                                                                  
1919             }                                                                                            
1920             Folder openFolder = mWorkspace.getOpenFolder();                                              
1921             // In all these cases, only animate if we're already on home                                 
1922             mWorkspace.exitWidgetResizeMode();                                                           
1923             boolean moveToDefaultScreen = (mLauncherCallbacks != null) ? mLauncherCallbacks.shouldMoveToD🔵
1924             if ((((alreadyOnHome && (mState == State.WORKSPACE)) && (!mWorkspace.isTouchActive())) && (op🔵
1925                 mWorkspace.moveToDefaultScreen(true);                                                    
1926             }                                                                                            
1927             closeFolder();                                                                               
1928             exitSpringLoadedDragMode();                                                                  
1929             // If we are already on home, then just animate back to the workspace,                       
1930             // otherwise, just wait until onResume to set the state back to Workspace                    
1931             if (alreadyOnHome) {                                                                         
1932                 showWorkspace(true);                                                                     
1933             } else {                                                                                     
1934                 mOnResumeState = State.WORKSPACE;                                                        
1935             }                                                                                            
1936             final View v = getWindow().peekDecorView();                                                  
1937             if ((v != null) && (v.getWindowToken() != null)) {                                           
1938                 InputMethodManager imm = ((InputMethodManager) (getSystemService(INPUT_METHOD_SERVICE)));
1939                 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                      
1940             }                                                                                            
1941             // Reset the apps view                                                                       
1942             if ((!alreadyOnHome) && (mAppsView != null)) {                                               
1943                 mAppsView.scrollToTop();                                                                 
1944             }                                                                                            
1945             // Reset the widgets view                                                                    
1946             if ((!alreadyOnHome) && (mWidgetsView != null)) {                                            
1947                 mWidgetsView.scrollToTop();                                                              
1948             }                                                                                            
1949             if (mLauncherCallbacks != null) {                                                            
1950                 mLauncherCallbacks.onHomeIntent();                                                       
1951             }                                                                                            
1952         }                                                                                                
1953         if (DEBUG_RESUME_TIME) {                                                                         
1954             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));        
1955         }                                                                                                
1956         if (mLauncherCallbacks != null) {                                                                
1957             mLauncherCallbacks.onNewIntent(intent);                                                      
1958         }                                                                                                
1959     }                                                                                                    
1960                                                                                                          
1961     @Override                                                                                            
1962     public void onRestoreInstanceState(Bundle state) {                                                   
1963         super.onRestoreInstanceState(state);                                                             
1964         for (int page: mSynchronouslyBoundPages) {                                                       
1965             mWorkspace.restoreInstanceStateForChild(page);                                               
1966         }                                                                                                
1967     }                                                                                                    
1968                                                                                                          
1969     @Override                                                                                            
1970     protected void onSaveInstanceState(Bundle outState) {                                                
1971         if (mWorkspace.getChildCount() > 0) {                                                            
1972             outState.putInt(RUNTIME_STATE_CURRENT_SCREEN, mWorkspace.getCurrentPageOffsetFromCustomConten🔵
1973         }                                                                                                
1974         super.onSaveInstanceState(outState);                                                             
1975         outState.putInt(RUNTIME_STATE, mState.ordinal());                                                
1976         // We close any open folder since it will not be re-opened, and we need to make sure             
1977         // this state is reflected.                                                                      
1978         closeFolder();                                                                                   
1979         if (((mPendingAddInfo.container != ItemInfo.NO_ID) && (mPendingAddInfo.screenId > (-1))) && mWait🔵
1980             outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);            
1981             outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                
1982             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                    
1983             outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                    
1984             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                    
1985             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                    
1986             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);        
1987             outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                   
1988         }                                                                                                
1989         if ((mFolderInfo != null) && mWaitingForResult) {                                                
1990             outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                              
1991             outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                    
1992         }                                                                                                
1993         // Save the current widgets tray?                                                                
1994         // TODO(hyunyoungs)                                                                              
1995         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                               
1996         if (mLauncherCallbacks != null) {                                                                
1997             mLauncherCallbacks.onSaveInstanceState(outState);                                            
1998         }                                                                                                
1999     }                                                                                                    
2000                                                                                                          
2001     @Override                                                                                            
2002     public void onDestroy() {                                                                            
2003         super.onDestroy();                                                                               
2004                                                                                                          
2005         // Remove all pending runnables                                                                  
2006         mHandler.removeMessages(ADVANCE_MSG);                                                            
2007         mHandler.removeMessages(0);                                                                      
2008         mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                
2009                                                                                                          
2010         // Stop callbacks from LauncherModel                                                             
2011         LauncherAppState app = (LauncherAppState.getInstance());                                         
2012                                                                                                          
2013         // It's possible to receive onDestroy after a new Launcher activity has                          
2014         // been created. In this case, don't interfere with the new Launcher.                            
2015         if (mModel.isCurrentCallbacks(this)) {                                                           
2016             mModel.stopLoader();                                                                         
2017             app.setLauncher(null);                                                                       
2018         }                                                                                                
2019                                                                                                          
2020         try {                                                                                            
2021             mAppWidgetHost.stopListening();                                                              
2022         } catch (NullPointerException ex) {                                                              
2023             Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);          
2024         }                                                                                                
2025         mAppWidgetHost = null;                                                                           
2026                                                                                                          
2027         mWidgetsToAdvance.clear();                                                                       
2028                                                                                                          
2029         TextKeyListener.getInstance().release();                                                         
2030                                                                                                          
2031         // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace      
2032         // to prevent leaking Launcher activities on orientation change.                                 
2033         if (mModel != null) {                                                                            
2034             mModel.unbindItemInfosAndClearQueuedBindRunnables();                                         
2035         }                                                                                                
2036                                                                                                          
2037         getContentResolver().unregisterContentObserver(mWidgetObserver);                                 
2038         unregisterReceiver(mCloseSystemDialogsReceiver);                                                 
2039                                                                                                          
2040         mDragLayer.clearAllResizeFrames();                                                               
2041         ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                           
2042         mWorkspace.removeAllWorkspaceScreens();                                                          
2043         mWorkspace = null;                                                                               
2044         mDragController = null;                                                                          
2045                                                                                                          
2046         LauncherAnimUtils.onDestroyActivity();                                                           
2047                                                                                                          
2048         if (mLauncherCallbacks != null) {                                                                
2049             mLauncherCallbacks.onDestroy();                                                              
2050         }                                                                                                
2051     }                                                                                                    
2052                                                                                                          
2053     public DragController getDragController() {                                                          
2054         return mDragController;                                                                          
2055     }                                                                                                    
2056                                                                                                          
2057     @Override                                                                                            
2058     public void startActivityForResult(Intent intent, int requestCode) {                                 
2059         onStartForResult(requestCode);                                                                   
2060         super.startActivityForResult(intent, requestCode);                                               
2061     }                                                                                                    
2062                                                                                                          
2063     @Override                                                                                            
2064     public void startIntentSenderForResult (IntentSender intent, int requestCode,                        
2065             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {       
2066         onStartForResult(requestCode);                                                                   
2067         try {                                                                                            
2068             super.startIntentSenderForResult(intent, requestCode,                                        
2069                 fillInIntent, flagsMask, flagsValues, extraFlags, options);                              
2070         } catch (IntentSender.SendIntentException e) {                                                   
2071             throw new ActivityNotFoundException();                                                       
2072         }                                                                                                
2073     }                                                                                                    
2074                                                                                                          
2075     private void onStartForResult(int requestCode) {                                                     
2076         if (requestCode >= 0) {                                                                          
2077             setWaitingForResult(true);                                                                   
2078         }                                                                                                
2079     }                                                                                                    
2080                                                                                                          
2081     /**                                                                                                  
2082      * Indicates that we want global search for this activity by setting the globalSearch                
2083      * argument for {@link #startSearch} to true.                                                        
2084      */                                                                                                  
2085     @Override                                                                                            
2086     public void startSearch(String initialQuery, boolean selectInitialQuery,                             
2087             Bundle appSearchData, boolean globalSearch) {                                                
2088                                                                                                          
2089         showWorkspace(true);                                                                             
2090                                                                                                          
2091         if (initialQuery == null) {                                                                      
2092             // Use any text typed in the launcher as the initial query                                   
2093             initialQuery = getTypedText();                                                               
2094         }                                                                                                
2095         if (appSearchData == null) {                                                                     
2096             appSearchData = new Bundle();                                                                
2097             appSearchData.putString("source", "launcher-search");                                        
2098         }                                                                                                
2099         Rect sourceBounds = new Rect();                                                                  
2100         if (mSearchDropTargetBar != null) {                                                              
2101             sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                    
2102         }                                                                                                
2103                                                                                                          
2104         boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                     
2105                 appSearchData, sourceBounds);                                                            
2106         if (clearTextImmediately) {                                                                      
2107             clearTypedText();                                                                            
2108         }                                                                                                
2109     }                                                                                                    
2110                                                                                                          
2111     /**                                                                                                  
2112      * Start a text search.                                                                              
2113      *                                                                                                   
2114      * @return {@code true} if the search will start immediately, so any further keypresses              
2115      * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue      
2116      * to buffer keypresses.                                                                             
2117      */                                                                                                  
2118     public boolean startSearch(String initialQuery,                                                      
2119             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2120         if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                         
2121             return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,       
2122                     sourceBounds);                                                                       
2123         }                                                                                                
2124                                                                                                          
2125         startGlobalSearch(initialQuery, selectInitialQuery,                                              
2126                 appSearchData, sourceBounds);                                                            
2127         return false;                                                                                    
2128     }                                                                                                    
2129                                                                                                          
2130     /**                                                                                                  
2131      * Starts the global search activity. This code is a copied from SearchManager                       
2132      */                                                                                                  
2133     private void startGlobalSearch(String initialQuery,                                                  
2134             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                       
2135         final SearchManager searchManager =                                                              
2136             (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                    
2137         ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                    
2138         if (globalSearchActivity == null) {                                                              
2139             Log.w(TAG, "No global search activity found.");                                              
2140             return;                                                                                      
2141         }                                                                                                
2142         Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                           
2143         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2144         intent.setComponent(globalSearchActivity);                                                       
2145         // Make sure that we have a Bundle to put source in                                              
2146         if (appSearchData == null) {                                                                     
2147             appSearchData = new Bundle();                                                                
2148         } else {                                                                                         
2149             appSearchData = new Bundle(appSearchData);                                                   
2150         }                                                                                                
2151         // Set source to package name of app that starts global search if not set already.               
2152         if (!appSearchData.containsKey("source")) {                                                      
2153             appSearchData.putString("source", getPackageName());                                         
2154         }                                                                                                
2155         intent.putExtra(SearchManager.APP_DATA, appSearchData);                                          
2156         if (!TextUtils.isEmpty(initialQuery)) {                                                          
2157             intent.putExtra(SearchManager.QUERY, initialQuery);                                          
2158         }                                                                                                
2159         if (selectInitialQuery) {                                                                        
2160             intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                       
2161         }                                                                                                
2162         intent.setSourceBounds(sourceBounds);                                                            
2163         try {                                                                                            
2164             startActivity(intent);                                                                       
2165         } catch (ActivityNotFoundException ex) {                                                         
2166             Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                     
2167         }                                                                                                
2168     }                                                                                                    
2169                                                                                                          
2170     public boolean isOnCustomContent() {                                                                 
2171         return mWorkspace.isOnOrMovingToCustomContent();                                                 
2172     }                                                                                                    
2173                                                                                                          
2174     @Override                                                                                            
2175     public boolean onPrepareOptionsMenu(Menu menu) {                                                     
2176         super.onPrepareOptionsMenu(menu);                                                                
2177         if (!isOnCustomContent()) {                                                                      
2178             // Close any open folders                                                                    
2179             closeFolder();                                                                               
2180             // Stop resizing any widgets                                                                 
2181             mWorkspace.exitWidgetResizeMode();                                                           
2182             if (!mWorkspace.isInOverviewMode()) {                                                        
2183                 // Show the overview mode                                                                
2184                 showOverviewMode(true);                                                                  
2185             } else {                                                                                     
2186                 showWorkspace(true);                                                                     
2187             }                                                                                            
2188         }                                                                                                
2189         if (mLauncherCallbacks != null) {                                                                
2190             return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                        
2191         }                                                                                                
2192                                                                                                          
2193         return false;                                                                                    
2194     }                                                                                                    
2195                                                                                                          
2196     @Override                                                                                            
2197     public boolean onSearchRequested() {                                                                 
2198         startSearch(null, false, null, true);                                                            
2199         // Use a custom animation for launching search                                                   
2200         return true;                                                                                     
2201     }                                                                                                    
2202                                                                                                          
2203     public boolean isWorkspaceLocked() {                                                                 
2204         return mWorkspaceLoading || mWaitingForResult;                                                   
2205     }                                                                                                    
2206                                                                                                          
2207     public boolean isWorkspaceLoading() {                                                                
2208         return mWorkspaceLoading;                                                                        
2209     }                                                                                                    
2210                                                                                                          
2211     private void setWorkspaceLoading(boolean value) {                                                    
2212         boolean isLocked = isWorkspaceLocked();                                                          
2213         mWorkspaceLoading = value;                                                                       
2214         if (isLocked != isWorkspaceLocked()) {                                                           
2215             onWorkspaceLockedChanged();                                                                  
2216         }                                                                                                
2217     }                                                                                                    
2218                                                                                                          
2219     private void setWaitingForResult(boolean value) {                                                    
2220         boolean isLocked = isWorkspaceLocked();                                                          
2221         mWaitingForResult = value;                                                                       
2222         if (isLocked != isWorkspaceLocked()) {                                                           
2223             onWorkspaceLockedChanged();                                                                  
2224         }                                                                                                
2225     }                                                                                                    
2226                                                                                                          
2227     protected void onWorkspaceLockedChanged() {                                                          
2228         if (mLauncherCallbacks != null) {                                                                
2229             mLauncherCallbacks.onWorkspaceLockedChanged();                                               
2230         }                                                                                                
2231     }                                                                                                    
2232                                                                                                          
2233     private void resetAddInfo() {                                                                        
2234         mPendingAddInfo.container = ItemInfo.NO_ID;                                                      
2235         mPendingAddInfo.screenId = -1;                                                                   
2236         mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                              
2237         mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                              
2238         mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                        
2239         mPendingAddInfo.dropPos = null;                                                                  
2240     }                                                                                                    
2241                                                                                                          
2242     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                              
2243             AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {          
2244         addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                              
2245     }                                                                                                    
2246                                                                                                          
2247     void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                    
2248             final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,      
2249             int delay) {                                                                                 
2250         if (appWidgetInfo.configure != null) {                                                           
2251             mPendingAddWidgetInfo = appWidgetInfo;                                                       
2252             mPendingAddWidgetId = appWidgetId;                                                           
2253                                                                                                          
2254             // Launch over to configure widget, if needed                                                
2255             mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                      
2256                     mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                           
2257                                                                                                          
2258         } else {                                                                                         
2259             // Otherwise just add it                                                                     
2260             Runnable onComplete = new Runnable() {                                                       
2261                 @Override                                                                                
2262                 public void run() {                                                                      
2263                     // Exit spring loaded mode if necessary after adding the widget                      
2264                     exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,          
2265                             null);                                                                       
2266                 }                                                                                        
2267             };                                                                                           
2268             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                
2269                     appWidgetInfo);                                                                      
2270             mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                    
2271         }                                                                                                
2272     }                                                                                                    
2273                                                                                                          
2274     protected void moveToCustomContentScreen(boolean animate) {                                          
2275         // Close any folders that may be open.                                                           
2276         closeFolder();                                                                                   
2277         mWorkspace.moveToCustomContentScreen(animate);                                                   
2278     }                                                                                                    
2279                                                                                                          
2280     public void addPendingItem(PendingAddItemInfo info, long container, long screenId, int[] cell, int sp🔵
2281         switch (info.itemType) {                                                                         
2282             case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET :                                 
2283             case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET :                                        
2284                 int[] span = new int[2];                                                                 
2285                 span[0] = spanX;                                                                         
2286                 span[1] = spanY;                                                                         
2287                 addAppWidgetFromDrop(((PendingAddWidgetInfo) (info)), container, screenId, cell, span);  
2288                 break;                                                                                   
2289             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT :                                         
2290                 processShortcutFromDrop(info.componentName, container, screenId, cell);                  
2291                 break;                                                                                   
2292             default :                                                                                    
2293                 throw new IllegalStateException("Unknown item type: " + info.itemType);                  
2294         }                                                                                                
2295     }                                                                                                    
2296                                                                                                          
2297     /**                                                                                                  
2298      * Process a shortcut drop.                                                                          
2299      *                                                                                                   
2300      * @param componentName The name of the component                                                    
2301      * @param screenId The ID of the screen where it should be added                                     
2302      * @param cell The cell it should be added to, optional                                              
2303      */                                                                                                  
2304     private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,     
2305             int[] cell) {                                                                                
2306         resetAddInfo();                                                                                  
2307         mPendingAddInfo.container = container;                                                           
2308         mPendingAddInfo.screenId = screenId;                                                             
2309         mPendingAddInfo.dropPos = null;                                                                  
2310                                                                                                          
2311         if (cell != null) {                                                                              
2312             mPendingAddInfo.cellX = cell[0];                                                             
2313             mPendingAddInfo.cellY = cell[1];                                                             
2314         }                                                                                                
2315                                                                                                          
2316         Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                         
2317         createShortcutIntent.setComponent(componentName);                                                
2318         processShortcut(createShortcutIntent);                                                           
2319     }                                                                                                    
2320                                                                                                          
2321     /**                                                                                                  
2322      * Process a widget drop.                                                                            
2323      *                                                                                                   
2324      * @param info The PendingAppWidgetInfo of the widget being added.                                   
2325      * @param screenId The ID of the screen where it should be added                                     
2326      * @param cell The cell it should be added to, optional                                              
2327      */                                                                                                  
2328     private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId, int[] cel🔵
2329         resetAddInfo();                                                                                  
2330         mPendingAddInfo.container = info.container = container;                                          
2331         mPendingAddInfo.screenId = info.screenId = screenId;                                             
2332         mPendingAddInfo.dropPos = null;                                                                  
2333         mPendingAddInfo.minSpanX = info.minSpanX;                                                        
2334         mPendingAddInfo.minSpanY = info.minSpanY;                                                        
2335         if (cell != null) {                                                                              
2336             mPendingAddInfo.cellX = cell[0];                                                             
2337             mPendingAddInfo.cellY = cell[1];                                                             
2338         }                                                                                                
2339         if (span != null) {                                                                              
2340             mPendingAddInfo.spanX = span[0];                                                             
2341             mPendingAddInfo.spanY = span[1];                                                             
2342         }                                                                                                
2343         AppWidgetHostView hostView = info.boundWidget;                                                   
2344         int appWidgetId;                                                                                 
2345         if (hostView != null) {                                                                          
2346             appWidgetId = hostView.getAppWidgetId();                                                     
2347             addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                    
2348         } else {                                                                                         
2349             // In this case, we either need to start an activity to get permission to bind               
2350             // the widget, or we need to start an activity to configure the widget, or both.             
2351             appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                      
2352             Bundle options = info.bindOptions;                                                           
2353             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, info.info, options)🔵
2354             if (success) {                                                                               
2355                 addAppWidgetImpl(appWidgetId, info, null, info.info);                                    
2356             } else {                                                                                     
2357                 mPendingAddWidgetInfo = info.info;                                                       
2358                 Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                      
2359                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                       
2360                 intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);          
2361                 mAppWidgetManager.getUser(mPendingAddWidgetInfo).addToIntent(intent, AppWidgetManager.EXT🔵
2362                 // TODO: we need to make sure that this accounts for the options bundle.                 
2363                 // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                   
2364                 startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                  
2365             }                                                                                            
2366         }                                                                                                
2367     }                                                                                                    
2368                                                                                                          
2369     void processShortcut(Intent intent) {                                                                
2370         Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                   
2371     }                                                                                                    
2372                                                                                                          
2373     void processWallpaper(Intent intent) {                                                               
2374         startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                          
2375     }                                                                                                    
2376                                                                                                          
2377     FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX, int cellY) { 
2378         final FolderInfo folderInfo = new FolderInfo();                                                  
2379         folderInfo.title = getText(R.string.folder_name);                                                
2380         // Update the model                                                                              
2381         LauncherModel.addItemToDatabase(this, folderInfo, container, screenId, cellX, cellY);            
2382         sFolders.put(folderInfo.id, folderInfo);                                                         
2383         // Create the view                                                                               
2384         FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCa🔵
2385         mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1, isWorkspaceLocked()); 
2386         // Force measure the new folder icon                                                             
2387         CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                            
2388         parent.getShortcutsAndWidgets().measureChild(newFolder);                                         
2389         return newFolder;                                                                                
2390     }                                                                                                    
2391                                                                                                          
2392     void removeFolder(FolderInfo folder) {                                                               
2393         sFolders.remove(folder.id);                                                                      
2394     }                                                                                                    
2395                                                                                                          
2396     /**                                                                                                  
2397      * Registers various content observers. The current implementation registers                         
2398      * only a favorites observer to keep track of the favorites applications.                            
2399      */                                                                                                  
2400     private void registerContentObservers() {                                                            
2401         ContentResolver resolver = getContentResolver();                                                 
2402         resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                   
2403                 true, mWidgetObserver);                                                                  
2404     }                                                                                                    
2405                                                                                                          
2406     @Override                                                                                            
2407     public boolean dispatchKeyEvent(KeyEvent event) {                                                    
2408         if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                 
2409             switch (event.getKeyCode()) {                                                                
2410                 case KeyEvent.KEYCODE_HOME:                                                              
2411                     return true;                                                                         
2412                 case KeyEvent.KEYCODE_VOLUME_DOWN:                                                       
2413                     if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                              
2414                         dumpState();                                                                     
2415                         return true;                                                                     
2416                     }                                                                                    
2417                     break;                                                                               
2418             }                                                                                            
2419         } else if (event.getAction() == KeyEvent.ACTION_UP) {                                            
2420             switch (event.getKeyCode()) {                                                                
2421                 case KeyEvent.KEYCODE_HOME:                                                              
2422                     return true;                                                                         
2423             }                                                                                            
2424         }                                                                                                
2425                                                                                                          
2426         return super.dispatchKeyEvent(event);                                                            
2427     }                                                                                                    
2428                                                                                                          
2429     @Override                                                                                            
2430     public void onBackPressed() {                                                                        
2431         if ((mLauncherCallbacks != null) && mLauncherCallbacks.handleBackPressed()) {                    
2432             return;                                                                                      
2433         }                                                                                                
2434         LauncherAccessibilityDelegate delegate = LauncherAppState.getInstance().getAccessibilityDelegate(🔵
2435         if ((delegate != null) && delegate.onBackPressed()) {                                            
2436             return;                                                                                      
2437         }                                                                                                
2438         if (isAppsViewVisible()) {                                                                       
2439             showWorkspace(true);                                                                         
2440         } else if (isWidgetsViewVisible()) {                                                             
2441             showOverviewMode(true);                                                                      
2442         } else if (mWorkspace.isInOverviewMode()) {                                                      
2443             mWorkspace.exitOverviewMode(true);                                                           
2444         } else if (mWorkspace.getOpenFolder() != null) {                                                 
2445             Folder openFolder = mWorkspace.getOpenFolder();                                              
2446             if (openFolder.isEditingName()) {                                                            
2447                 openFolder.dismissEditingName();                                                         
2448             } else {                                                                                     
2449                 closeFolder();                                                                           
2450             }                                                                                            
2451         } else {                                                                                         
2452             mWorkspace.exitWidgetResizeMode();                                                           
2453             // Back button is a no-op here, but give at least some feedback for the button press         
2454             mWorkspace.showOutlinesTemporarily();                                                        
2455         }                                                                                                
2456     }                                                                                                    
2457                                                                                                          
2458     /**                                                                                                  
2459      * Re-listen when widgets are reset.                                                                 
2460      */                                                                                                  
2461     @Thunk                                                                                               
2462     void onAppWidgetReset() {                                                                            
2463         if (mAppWidgetHost != null) {                                                                    
2464             mAppWidgetHost.startListening();                                                             
2465         }                                                                                                
2466     }                                                                                                    
2467                                                                                                          
2468     /**                                                                                                  
2469      * Launches the intent referred by the clicked shortcut.                                             
2470      *                                                                                                   
2471      * @param v The view representing the clicked shortcut.                                              
2472      */                                                                                                  
2473     public void onClick(View v) {                                                                        
2474         // Make sure that rogue clicks don't get through while allapps is launching, or after the        
2475         // view has detached (it's possible for this to happen if the view is removed mid touch).        
2476         if (v.getWindowToken() == null) {                                                                
2477             return;                                                                                      
2478         }                                                                                                
2479                                                                                                          
2480         if (!mWorkspace.isFinishedSwitchingState()) {                                                    
2481             return;                                                                                      
2482         }                                                                                                
2483                                                                                                          
2484         if (v instanceof Workspace) {                                                                    
2485             if (mWorkspace.isInOverviewMode()) {                                                         
2486                 mWorkspace.exitOverviewMode(true);                                                       
2487             }                                                                                            
2488             return;                                                                                      
2489         }                                                                                                
2490                                                                                                          
2491         if (v instanceof CellLayout) {                                                                   
2492             if (mWorkspace.isInOverviewMode()) {                                                         
2493                 mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                           
2494             }                                                                                            
2495         }                                                                                                
2496                                                                                                          
2497         Object tag = v.getTag();                                                                         
2498         if (tag instanceof ShortcutInfo) {                                                               
2499             onClickAppShortcut(v);                                                                       
2500         } else if (tag instanceof FolderInfo) {                                                          
2501             if (v instanceof FolderIcon) {                                                               
2502                 onClickFolderIcon(v);                                                                    
2503             }                                                                                            
2504         } else if (v == mAllAppsButton) {                                                                
2505             onClickAllAppsButton(v);                                                                     
2506         } else if (tag instanceof AppInfo) {                                                             
2507             startAppShortcutOrInfoActivity(v);                                                           
2508         } else if (tag instanceof LauncherAppWidgetInfo) {                                               
2509             if (v instanceof PendingAppWidgetHostView) {                                                 
2510                 onClickPendingWidget((PendingAppWidgetHostView) v);                                      
2511             }                                                                                            
2512         }                                                                                                
2513     }                                                                                                    
2514                                                                                                          
2515     public void onClickPagedViewIcon(View v) {                                                           
2516         startAppShortcutOrInfoActivity(v);                                                               
2517         if (mLauncherCallbacks != null) {                                                                
2518             mLauncherCallbacks.onClickPagedViewIcon(v);                                                  
2519         }                                                                                                
2520     }                                                                                                    
2521                                                                                                          
2522     public boolean onTouch(View v, MotionEvent event) {                                                  
2523         return false;                                                                                    
2524     }                                                                                                    
2525                                                                                                          
2526     /**                                                                                                  
2527      * Event handler for the app widget view which has not fully restored.                               
2528      */                                                                                                  
2529     public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                 
2530         if (mIsSafeModeEnabled) {                                                                        
2531             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2532             return;                                                                                      
2533         }                                                                                                
2534                                                                                                          
2535         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                           
2536         if (v.isReadyForClickSetup()) {                                                                  
2537             int widgetId = info.appWidgetId;                                                             
2538             AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);          
2539             if (appWidgetInfo != null) {                                                                 
2540                 mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                  
2541                         this, appWidgetInfo);                                                            
2542                 mPendingAddInfo.copyFrom(info);                                                          
2543                 mPendingAddWidgetId = widgetId;                                                          
2544                                                                                                          
2545                 AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,              
2546                         info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);          
2547             }                                                                                            
2548         } else if (info.installProgress < 0) {                                                           
2549             // The install has not been queued                                                           
2550             final String packageName = info.providerName.getPackageName();                               
2551             showBrokenAppInstallDialog(packageName,                                                      
2552                 new DialogInterface.OnClickListener() {                                                  
2553                     public void onClick(DialogInterface dialog, int id) {                                
2554                         startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);        
2555                     }                                                                                    
2556                 });                                                                                      
2557         } else {                                                                                         
2558             // Download has started.                                                                     
2559             final String packageName = info.providerName.getPackageName();                               
2560             startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                    
2561         }                                                                                                
2562     }                                                                                                    
2563                                                                                                          
2564     /**                                                                                                  
2565      * Event handler for the "grid" button that appears on the home screen, which                        
2566      * enters all apps mode.                                                                             
2567      *                                                                                                   
2568      * @param v The view that was clicked.                                                               
2569      */                                                                                                  
2570     protected void onClickAllAppsButton(View v) {                                                        
2571         if (LOGD) {                                                                                      
2572             Log.d(TAG, "onClickAllAppsButton");                                                          
2573         }                                                                                                
2574         if (isAppsViewVisible()) {                                                                       
2575             showWorkspace(true);                                                                         
2576         } else {                                                                                         
2577             /* animated */                                                                               
2578             /* resetListToTop */                                                                         
2579             showAppsView(true, false);                                                                   
2580         }                                                                                                
2581     }                                                                                                    
2582                                                                                                          
2583     private void showBrokenAppInstallDialog(final String packageName,                                    
2584             DialogInterface.OnClickListener onSearchClickListener) {                                     
2585         new AlertDialog.Builder(this)                                                                    
2586             .setTitle(R.string.abandoned_promises_title)                                                 
2587             .setMessage(R.string.abandoned_promise_explanation)                                          
2588             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                         
2589             .setNeutralButton(R.string.abandoned_clean_this,                                             
2590                 new DialogInterface.OnClickListener() {                                                  
2591                     public void onClick(DialogInterface dialog, int id) {                                
2592                         final UserHandleCompat user = UserHandleCompat.myUserHandle();                   
2593                         mWorkspace.removeAbandonedPromise(packageName, user);                            
2594                     }                                                                                    
2595                 })                                                                                       
2596             .create().show();                                                                            
2597         return;                                                                                          
2598     }                                                                                                    
2599                                                                                                          
2600     /**                                                                                                  
2601      * Event handler for an app shortcut click.                                                          
2602      *                                                                                                   
2603      * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                 
2604      */                                                                                                  
2605     protected void onClickAppShortcut(final View v) {                                                    
2606         if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                      
2607         Object tag = v.getTag();                                                                         
2608         if (!(tag instanceof ShortcutInfo)) {                                                            
2609             throw new IllegalArgumentException("Input must be a Shortcut");                              
2610         }                                                                                                
2611                                                                                                          
2612         // Open shortcut                                                                                 
2613         final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                
2614                                                                                                          
2615         if (shortcut.isDisabled != 0) {                                                                  
2616             int error = R.string.activity_not_available;                                                 
2617             if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                      
2618                 error = R.string.safemode_shortcut_error;                                                
2619             }                                                                                            
2620             Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                      
2621             return;                                                                                      
2622         }                                                                                                
2623                                                                                                          
2624         final Intent intent = shortcut.intent;                                                           
2625                                                                                                          
2626         // Check for special shortcuts                                                                   
2627         if (intent.getComponent() != null) {                                                             
2628             final String shortcutClass = intent.getComponent().getClassName();                           
2629                                                                                                          
2630             if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                              
2631                 MemoryDumpActivity.startDump(this);                                                      
2632                 return;                                                                                  
2633             } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                      
2634                 toggleShowWeightWatcher();                                                               
2635                 return;                                                                                  
2636             }                                                                                            
2637         }                                                                                                
2638                                                                                                          
2639         // Check for abandoned promise                                                                   
2640         if ((v instanceof BubbleTextView)                                                                
2641                 && shortcut.isPromise()                                                                  
2642                 && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                  
2643             showBrokenAppInstallDialog(                                                                  
2644                     shortcut.getTargetComponent().getPackageName(),                                      
2645                     new DialogInterface.OnClickListener() {                                              
2646                         public void onClick(DialogInterface dialog, int id) {                            
2647                             startAppShortcutOrInfoActivity(v);                                           
2648                         }                                                                                
2649                     });                                                                                  
2650             return;                                                                                      
2651         }                                                                                                
2652                                                                                                          
2653         // Start activities                                                                              
2654         startAppShortcutOrInfoActivity(v);                                                               
2655                                                                                                          
2656         if (mLauncherCallbacks != null) {                                                                
2657             mLauncherCallbacks.onClickAppShortcut(v);                                                    
2658         }                                                                                                
2659     }                                                                                                    
2660                                                                                                          
2661     @Thunk                                                                                               
2662     void startAppShortcutOrInfoActivity(View v) {                                                        
2663         Object tag = v.getTag();                                                                         
2664         final ShortcutInfo shortcut;                                                                     
2665         final Intent intent;                                                                             
2666         if (tag instanceof ShortcutInfo) {                                                               
2667             shortcut = ((ShortcutInfo) (tag));                                                           
2668             intent = shortcut.intent;                                                                    
2669             int[] pos = new int[2];                                                                      
2670             v.getLocationOnScreen(pos);                                                                  
2671             intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight()🔵
2672         } else if (tag instanceof AppInfo) {                                                             
2673             shortcut = null;                                                                             
2674             intent = ((AppInfo) (tag)).intent;                                                           
2675         } else {                                                                                         
2676             throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                   
2677         }                                                                                                
2678         boolean success = startActivitySafely(v, intent, tag);                                           
2679         mStats.recordLaunch(intent, shortcut);                                                           
2680         if (success && (v instanceof BubbleTextView)) {                                                  
2681             mWaitingForResume = ((BubbleTextView) (v));                                                  
2682             mWaitingForResume.setStayPressed(true);                                                      
2683         }                                                                                                
2684     }                                                                                                    
2685                                                                                                          
2686     /**                                                                                                  
2687      * Event handler for a folder icon click.                                                            
2688      *                                                                                                   
2689      * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                    
2690      */                                                                                                  
2691     protected void onClickFolderIcon(View v) {                                                           
2692         if (LOGD) Log.d(TAG, "onClickFolder");                                                           
2693         if (!(v instanceof FolderIcon)){                                                                 
2694             throw new IllegalArgumentException("Input must be a FolderIcon");                            
2695         }                                                                                                
2696                                                                                                          
2697         FolderIcon folderIcon = (FolderIcon) v;                                                          
2698         final FolderInfo info = folderIcon.getFolderInfo();                                              
2699         Folder openFolder = mWorkspace.getFolderForTag(info);                                            
2700                                                                                                          
2701         // If the folder info reports that the associated folder is open, then verify that               
2702         // it is actually opened. There have been a few instances where this gets out of sync.           
2703         if (info.opened && openFolder == null) {                                                         
2704             Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "         
2705                     + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                      
2706             info.opened = false;                                                                         
2707         }                                                                                                
2708                                                                                                          
2709         if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                     
2710             // Close any open folder                                                                     
2711             closeFolder();                                                                               
2712             // Open the requested folder                                                                 
2713             openFolder(folderIcon);                                                                      
2714         } else {                                                                                         
2715             // Find the open folder...                                                                   
2716             int folderScreen;                                                                            
2717             if (openFolder != null) {                                                                    
2718                 folderScreen = mWorkspace.getPageForView(openFolder);                                    
2719                 // .. and close it                                                                       
2720                 closeFolder(openFolder);                                                                 
2721                 if (folderScreen != mWorkspace.getCurrentPage()) {                                       
2722                     // Close any folder open on the current screen                                       
2723                     closeFolder();                                                                       
2724                     // Pull the folder onto this screen                                                  
2725                     openFolder(folderIcon);                                                              
2726                 }                                                                                        
2727             }                                                                                            
2728         }                                                                                                
2729                                                                                                          
2730         if (mLauncherCallbacks != null) {                                                                
2731             mLauncherCallbacks.onClickFolderIcon(v);                                                     
2732         }                                                                                                
2733     }                                                                                                    
2734                                                                                                          
2735     /**                                                                                                  
2736      * Event handler for the (Add) Widgets button that appears after a long press                        
2737      * on the home screen.                                                                               
2738      */                                                                                                  
2739     protected void onClickAddWidgetButton(View view) {                                                   
2740         if (LOGD) {                                                                                      
2741             Log.d(TAG, "onClickAddWidgetButton");                                                        
2742         }                                                                                                
2743         if (mIsSafeModeEnabled) {                                                                        
2744             Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();             
2745         } else {                                                                                         
2746             /* animated */                                                                               
2747             /* resetPageToZero */                                                                        
2748             showWidgetsView(true, true);                                                                 
2749             if (mLauncherCallbacks != null) {                                                            
2750                 mLauncherCallbacks.onClickAddWidgetButton(view);                                         
2751             }                                                                                            
2752         }                                                                                                
2753     }                                                                                                    
2754                                                                                                          
2755     /**                                                                                                  
2756      * Event handler for the wallpaper picker button that appears after a long press                     
2757      * on the home screen.                                                                               
2758      */                                                                                                  
2759     protected void onClickWallpaperPicker(View v) {                                                      
2760         if (LOGD) {                                                                                      
2761             Log.d(TAG, "onClickWallpaperPicker");                                                        
2762         }                                                                                                
2763         startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()), REQU🔵
2764         if (mLauncherCallbacks != null) {                                                                
2765             mLauncherCallbacks.onClickWallpaperPicker(v);                                                
2766         }                                                                                                
2767     }                                                                                                    
2768                                                                                                          
2769     /**                                                                                                  
2770      * Event handler for a click on the settings button that appears after a long press                  
2771      * on the home screen.                                                                               
2772      */                                                                                                  
2773     protected void onClickSettingsButton(View v) {                                                       
2774         if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                   
2775         if (mLauncherCallbacks != null) {                                                                
2776             mLauncherCallbacks.onClickSettingsButton(v);                                                 
2777         }                                                                                                
2778     }                                                                                                    
2779                                                                                                          
2780     public void onTouchDownAllAppsButton(View v) {                                                       
2781         // Provide the same haptic feedback that the system offers for virtual keys.                     
2782         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2783     }                                                                                                    
2784                                                                                                          
2785     public void performHapticFeedbackOnTouchDown(View v) {                                               
2786         // Provide the same haptic feedback that the system offers for virtual keys.                     
2787         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                    
2788     }                                                                                                    
2789                                                                                                          
2790     public View.OnTouchListener getHapticFeedbackTouchListener() {                                       
2791         if (mHapticFeedbackTouchListener == null) {                                                      
2792             mHapticFeedbackTouchListener = new View.OnTouchListener() {                                  
2793                 @Override                                                                                
2794                 public boolean onTouch(View v, MotionEvent event) {                                      
2795                     if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {      
2796                         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                    
2797                     }                                                                                    
2798                     return false;                                                                        
2799                 }                                                                                        
2800             };                                                                                           
2801         }                                                                                                
2802         return mHapticFeedbackTouchListener;                                                             
2803     }                                                                                                    
2804                                                                                                          
2805     public void onDragStarted(View view) {                                                               
2806         if (isOnCustomContent()) {                                                                       
2807             // Custom content screen doesn't participate in drag and drop. If on custom                  
2808             // content screen, move to default.                                                          
2809             moveWorkspaceToDefaultScreen();                                                              
2810         }                                                                                                
2811                                                                                                          
2812         if (mLauncherCallbacks != null) {                                                                
2813             mLauncherCallbacks.onDragStarted(view);                                                      
2814         }                                                                                                
2815     }                                                                                                    
2816                                                                                                          
2817     /**                                                                                                  
2818      * Called when the user stops interacting with the launcher.                                         
2819      * This implies that the user is now on the homescreen and is not doing housekeeping.                
2820      */                                                                                                  
2821     protected void onInteractionEnd() {                                                                  
2822         if (mLauncherCallbacks != null) {                                                                
2823             mLauncherCallbacks.onInteractionEnd();                                                       
2824         }                                                                                                
2825     }                                                                                                    
2826                                                                                                          
2827     /**                                                                                                  
2828      * Called when the user starts interacting with the launcher.                                        
2829      * The possible interactions are:                                                                    
2830      *  - open all apps                                                                                  
2831      *  - reorder an app shortcut, or a widget                                                           
2832      *  - open the overview mode.                                                                        
2833      * This is a good time to stop doing things that only make sense                                     
2834      * when the user is on the homescreen and not doing housekeeping.                                    
2835      */                                                                                                  
2836     protected void onInteractionBegin() {                                                                
2837         if (mLauncherCallbacks != null) {                                                                
2838             mLauncherCallbacks.onInteractionBegin();                                                     
2839         }                                                                                                
2840     }                                                                                                    
2841                                                                                                          
2842     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {           
2843         try {                                                                                            
2844             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2845             launcherApps.showAppDetailsForProfile(componentName, user);                                  
2846         } catch (SecurityException e) {                                                                  
2847             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2848             Log.e(TAG, "Launcher does not have permission to launch settings");                          
2849         } catch (ActivityNotFoundException e) {                                                          
2850             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2851             Log.e(TAG, "Unable to launch settings");                                                     
2852         }                                                                                                
2853     }                                                                                                    
2854                                                                                                          
2855     // returns true if the activity was started                                                          
2856     boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                    
2857             UserHandleCompat user) {                                                                     
2858         if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                    
2859             // System applications cannot be installed. For now, show a toast explaining that.           
2860             // We may give them the option of disabling apps this way.                                   
2861             int messageId = R.string.uninstall_system_app_text;                                          
2862             Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                  
2863             return false;                                                                                
2864         } else {                                                                                         
2865             String packageName = componentName.getPackageName();                                         
2866             String className = componentName.getClassName();                                             
2867             Intent intent = new Intent(                                                                  
2868                     Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));             
2869             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                              
2870                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                          
2871             if (user != null) {                                                                          
2872                 user.addToIntent(intent, Intent.EXTRA_USER);                                             
2873             }                                                                                            
2874             startActivity(intent);                                                                       
2875             return true;                                                                                 
2876         }                                                                                                
2877     }                                                                                                    
2878                                                                                                          
2879     boolean startActivity(View v, Intent intent, Object tag) {                                           
2880         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                  
2881         try {                                                                                            
2882             // Only launch using the new animation if the shortcut has not opted out (this is a          
2883             // private contract between launcher and may be ignored in the future).                      
2884             boolean useLaunchAnimation = (v != null) && (!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIM🔵
2885             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                      
2886             UserManagerCompat userManager = UserManagerCompat.getInstance(this);                         
2887             UserHandleCompat user = null;                                                                
2888             if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                
2889                 long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                      
2890                 user = userManager.getUserForSerialNumber(serialNumber);                                 
2891             }                                                                                            
2892             Bundle optsBundle = null;                                                                    
2893             if (useLaunchAnimation) {                                                                    
2894                 ActivityOptions opts = null;                                                             
2895                 if (sClipRevealMethod != null) {                                                         
2896                     // TODO: call method directly when Launcher3 can depend on M APIs                    
2897                     int left = 0;                                                                        
2898                     int top = 0;                                                                         
2899                     int width = v.getMeasuredWidth();                                                    
2900                     int height = v.getMeasuredHeight();                                                  
2901                     if (v instanceof TextView) {                                                         
2902                         // Launch from center of icon, not entire view                                   
2903                         Drawable icon = Workspace.getTextViewIcon(((TextView) (v)));                     
2904                         if (icon != null) {                                                              
2905                             Rect bounds = icon.getBounds();                                              
2906                             left = (width - bounds.width()) / 2;                                         
2907                             top = v.getPaddingTop();                                                     
2908                             width = bounds.width();                                                      
2909                             height = bounds.height();                                                    
2910                         }                                                                                
2911                     }                                                                                    
2912                     try {                                                                                
2913                         opts = ((ActivityOptions) (sClipRevealMethod.invoke(null, v, left, top, width, he🔵
2914                     } catch (java.lang.IllegalAccessException e) {                                       
2915                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2916                         sClipRevealMethod = null;                                                        
2917                     } catch (InvocationTargetException e) {                                              
2918                         Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                      
2919                         sClipRevealMethod = null;                                                        
2920                     }                                                                                    
2921                 }                                                                                        
2922                 if ((opts == null) && (!Utilities.isLmpOrAbove())) {                                     
2923                     opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasu🔵
2924                 }                                                                                        
2925                 optsBundle = (opts != null) ? opts.toBundle() : null;                                    
2926             }                                                                                            
2927             if ((user == null) || user.equals(UserHandleCompat.myUserHandle())) {                        
2928                 // Could be launching some bookkeeping activity                                          
2929                 startActivity(intent, optsBundle);                                                       
2930             } else {                                                                                     
2931                 // TODO Component can be null when shortcuts are supported for secondary user            
2932                 launcherApps.startActivityForProfile(intent.getComponent(), user, intent.getSourceBounds(🔵
2933             }                                                                                            
2934             return true;                                                                                 
2935         } catch (java.lang.SecurityException e) {                                                        
2936             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2937             Log.e(TAG, (((((("Launcher does not have the permission to launch " + intent) + ". Make sure 🔵
2938         }                                                                                                
2939         return false;                                                                                    
2940     }                                                                                                    
2941                                                                                                          
2942     boolean startActivitySafely(View v, Intent intent, Object tag) {                                     
2943         boolean success = false;                                                                         
2944         if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                
2945             Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();           
2946             return false;                                                                                
2947         }                                                                                                
2948         try {                                                                                            
2949             success = startActivity(v, intent, tag);                                                     
2950         } catch (ActivityNotFoundException e) {                                                          
2951             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                
2952             Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                         
2953         }                                                                                                
2954         return success;                                                                                  
2955     }                                                                                                    
2956                                                                                                          
2957     /**                                                                                                  
2958      * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView       
2959      * in the DragLayer in the exact absolute location of the original FolderIcon.                       
2960      */                                                                                                  
2961     private void copyFolderIconToImage(FolderIcon fi) {                                                  
2962         final int width = fi.getMeasuredWidth();                                                         
2963         final int height = fi.getMeasuredHeight();                                                       
2964                                                                                                          
2965         // Lazy load ImageView, Bitmap and Canvas                                                        
2966         if (mFolderIconImageView == null) {                                                              
2967             mFolderIconImageView = new ImageView(this);                                                  
2968         }                                                                                                
2969         if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                        
2970                 mFolderIconBitmap.getHeight() != height) {                                               
2971             mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);             
2972             mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                           
2973         }                                                                                                
2974                                                                                                          
2975         DragLayer.LayoutParams lp;                                                                       
2976         if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                  
2977             lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                        
2978         } else {                                                                                         
2979             lp = new DragLayer.LayoutParams(width, height);                                              
2980         }                                                                                                
2981                                                                                                          
2982         // The layout from which the folder is being opened may be scaled, adjust the starting           
2983         // view size by this scale factor.                                                               
2984         float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);           
2985         lp.customPosition = true;                                                                        
2986         lp.x = mRectForFolderAnimation.left;                                                             
2987         lp.y = mRectForFolderAnimation.top;                                                              
2988         lp.width = (int) (scale * width);                                                                
2989         lp.height = (int) (scale * height);                                                              
2990                                                                                                          
2991         mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                           
2992         fi.draw(mFolderIconCanvas);                                                                      
2993         mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                          
2994         if (fi.getFolder() != null) {                                                                    
2995             mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                  
2996             mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                  
2997         }                                                                                                
2998         // Just in case this image view is still in the drag layer from a previous animation,            
2999         // we remove it and re-add it.                                                                   
3000         if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                       
3001             mDragLayer.removeView(mFolderIconImageView);                                                 
3002         }                                                                                                
3003         mDragLayer.addView(mFolderIconImageView, lp);                                                    
3004         if (fi.getFolder() != null) {                                                                    
3005             fi.getFolder().bringToFront();                                                               
3006         }                                                                                                
3007     }                                                                                                    
3008                                                                                                          
3009     private void growAndFadeOutFolderIcon(FolderIcon fi) {                                               
3010         if (fi == null) return;                                                                          
3011         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                           
3012         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                      
3013         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                      
3014                                                                                                          
3015         FolderInfo info = (FolderInfo) fi.getTag();                                                      
3016         if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                            
3017             CellLayout cl = (CellLayout) fi.getParent().getParent();                                     
3018             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                 
3019             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                             
3020         }                                                                                                
3021                                                                                                          
3022         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original             
3023         copyFolderIconToImage(fi);                                                                       
3024         fi.setVisibility(View.INVISIBLE);                                                                
3025                                                                                                          
3026         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3027                 scaleX, scaleY);                                                                         
3028         if (Utilities.isLmpOrAbove()) {                                                                  
3029             oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                   
3030         }                                                                                                
3031         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3032         oa.start();                                                                                      
3033     }                                                                                                    
3034                                                                                                          
3035     private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                        
3036         if (fi == null) return;                                                                          
3037         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                        
3038         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                      
3039         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                      
3040                                                                                                          
3041         final CellLayout cl = (CellLayout) fi.getParent().getParent();                                   
3042                                                                                                          
3043         // We remove and re-draw the FolderIcon in-case it has changed                                   
3044         mDragLayer.removeView(mFolderIconImageView);                                                     
3045         copyFolderIconToImage(fi);                                                                       
3046         ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,        
3047                 scaleX, scaleY);                                                                         
3048         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                
3049         oa.addListener(new AnimatorListenerAdapter() {                                                   
3050             @Override                                                                                    
3051             public void onAnimationEnd(Animator animation) {                                             
3052                 if (cl != null) {                                                                        
3053                     cl.clearFolderLeaveBehind();                                                         
3054                     // Remove the ImageView copy of the FolderIcon and make the original visible.        
3055                     mDragLayer.removeView(mFolderIconImageView);                                         
3056                     fi.setVisibility(View.VISIBLE);                                                      
3057                 }                                                                                        
3058             }                                                                                            
3059         });                                                                                              
3060         oa.start();                                                                                      
3061     }                                                                                                    
3062                                                                                                          
3063     /**                                                                                                  
3064      * Opens the user folder described by the specified tag. The opening of the folder                   
3065      * is animated relative to the specified View. If the View is null, no animation                     
3066      * is played.                                                                                        
3067      *                                                                                                   
3068      * @param folderInfo The FolderInfo describing the folder to open.                                   
3069      */                                                                                                  
3070     public void openFolder(FolderIcon folderIcon) {                                                      
3071         Folder folder = folderIcon.getFolder();                                                          
3072         Folder openFolder = (mWorkspace != null) ? mWorkspace.getOpenFolder() : null;                    
3073         if ((openFolder != null) && (openFolder != folder)) {                                            
3074             // Close any open folder before opening a folder.                                            
3075             closeFolder();                                                                               
3076         }                                                                                                
3077         FolderInfo info = folder.mInfo;                                                                  
3078         info.opened = true;                                                                              
3079         // While the folder is open, the position of the icon cannot change.                             
3080         ((CellLayout.LayoutParams) (folderIcon.getLayoutParams())).canReorder = false;                   
3081         // Just verify that the folder hasn't already been added to the DragLayer.                       
3082         // There was a one-off crash where the folder had a parent already.                              
3083         if (folder.getParent() == null) {                                                                
3084             mDragLayer.addView(folder);                                                                  
3085             mDragController.addDropTarget(((DropTarget) (folder)));                                      
3086         } else {                                                                                         
3087             Log.w(TAG, ((("Opening folder (" + folder) + ") which already has a parent (") + folder.getPa🔵
3088         }                                                                                                
3089         folder.animateOpen();                                                                            
3090         growAndFadeOutFolderIcon(folderIcon);                                                            
3091         // Notify the accessibility manager that this folder "window" has appeared and occluded          
3092         // the workspace items                                                                           
3093         folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                     
3094         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);           
3095     }                                                                                                    
3096                                                                                                          
3097     public void closeFolder() {                                                                          
3098         Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                          
3099         if (folder != null) {                                                                            
3100             if (folder.isEditingName()) {                                                                
3101                 folder.dismissEditingName();                                                             
3102             }                                                                                            
3103             closeFolder(folder);                                                                         
3104         }                                                                                                
3105     }                                                                                                    
3106                                                                                                          
3107     void closeFolder(Folder folder) {                                                                    
3108         folder.getInfo().opened = false;                                                                 
3109         ViewGroup parent = ((ViewGroup) (folder.getParent().getParent()));                               
3110         if (parent != null) {                                                                            
3111             FolderIcon fi = ((FolderIcon) (mWorkspace.getViewForTag(folder.mInfo)));                     
3112             shrinkAndFadeInFolderIcon(fi);                                                               
3113             if (fi != null) {                                                                            
3114                 ((CellLayout.LayoutParams) (fi.getLayoutParams())).canReorder = true;                    
3115             }                                                                                            
3116         }                                                                                                
3117         folder.animateClosed();                                                                          
3118         // Notify the accessibility manager that this folder "window" has disappeard and no              
3119         // longer occludeds the workspace items                                                          
3120         getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);             
3121     }                                                                                                    
3122                                                                                                          
3123     public boolean onLongClick(View v) {                                                                 
3124         if (!isDraggingEnabled()) return false;                                                          
3125         if (isWorkspaceLocked()) return false;                                                           
3126         if (mState != State.WORKSPACE) return false;                                                     
3127                                                                                                          
3128         if (v instanceof Workspace) {                                                                    
3129             if (!mWorkspace.isInOverviewMode()) {                                                        
3130                 if (mWorkspace.enterOverviewMode()) {                                                    
3131                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                 
3132                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                           
3133                     return true;                                                                         
3134                 } else {                                                                                 
3135                     return false;                                                                        
3136                 }                                                                                        
3137             } else {                                                                                     
3138                 return false;                                                                            
3139             }                                                                                            
3140         }                                                                                                
3141                                                                                                          
3142         CellLayout.CellInfo longClickCellInfo = null;                                                    
3143         View itemUnderLongClick = null;                                                                  
3144         if (v.getTag() instanceof ItemInfo) {                                                            
3145             ItemInfo info = (ItemInfo) v.getTag();                                                       
3146             longClickCellInfo = new CellLayout.CellInfo(v, info);;                                       
3147             itemUnderLongClick = longClickCellInfo.cell;                                                 
3148             resetAddInfo();                                                                              
3149         }                                                                                                
3150                                                                                                          
3151         // The hotseat touch handling does not go through Workspace, and we always allow long press      
3152         // on hotseat items.                                                                             
3153         final boolean inHotseat = isHotseatLayout(v);                                                    
3154         boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                               
3155         if (allowLongPress && !mDragController.isDragging()) {                                           
3156             if (itemUnderLongClick == null) {                                                            
3157                 // User long pressed on empty space                                                      
3158                 mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                     
3159                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                               
3160                 if (mWorkspace.isInOverviewMode()) {                                                     
3161                     mWorkspace.startReordering(v);                                                       
3162                 } else {                                                                                 
3163                     mWorkspace.enterOverviewMode();                                                      
3164                 }                                                                                        
3165             } else {                                                                                     
3166                 final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                        
3167                         mHotseat.getOrderInHotseat(                                                      
3168                                 longClickCellInfo.cellX,                                                 
3169                                 longClickCellInfo.cellY));                                               
3170                 if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                        
3171                     // User long pressed on an item                                                      
3172                     mWorkspace.startDrag(longClickCellInfo);                                             
3173                 }                                                                                        
3174             }                                                                                            
3175         }                                                                                                
3176         return true;                                                                                     
3177     }                                                                                                    
3178                                                                                                          
3179     boolean isHotseatLayout(View layout) {                                                               
3180         return mHotseat != null && layout != null &&                                                     
3181                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                      
3182     }                                                                                                    
3183                                                                                                          
3184     /**                                                                                                  
3185      * Returns the CellLayout of the specified container at the specified screen.                        
3186      */                                                                                                  
3187     public CellLayout getCellLayout(long container, long screenId) {                                     
3188         if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                 
3189             if (mHotseat != null) {                                                                      
3190                 return mHotseat.getLayout();                                                             
3191             } else {                                                                                     
3192                 return null;                                                                             
3193             }                                                                                            
3194         } else {                                                                                         
3195             return mWorkspace.getScreenWithId(screenId);                                                 
3196         }                                                                                                
3197     }                                                                                                    
3198                                                                                                          
3199     /**                                                                                                  
3200      * For overridden classes.                                                                           
3201      */                                                                                                  
3202     public boolean isAllAppsVisible() {                                                                  
3203         return isAppsViewVisible();                                                                      
3204     }                                                                                                    
3205                                                                                                          
3206     public boolean isAppsViewVisible() {                                                                 
3207         return (mState == State.APPS) || (mOnResumeState == State.APPS);                                 
3208     }                                                                                                    
3209                                                                                                          
3210     public boolean isWidgetsViewVisible() {                                                              
3211         return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                           
3212     }                                                                                                    
3213                                                                                                          
3214     private void setWorkspaceBackground(boolean workspace) {                                             
3215         mLauncherView.setBackground(workspace ?                                                          
3216                 mWorkspaceBackgroundDrawable : null);                                                    
3217     }                                                                                                    
3218                                                                                                          
3219     protected void changeWallpaperVisiblity(boolean visible) {                                           
3220         int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                      
3221         int curflags = getWindow().getAttributes().flags                                                 
3222                 & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                        
3223         if (wpflags != curflags) {                                                                       
3224             getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);               
3225         }                                                                                                
3226         setWorkspaceBackground(visible);                                                                 
3227     }                                                                                                    
3228                                                                                                          
3229     @Override                                                                                            
3230     public void onTrimMemory(int level) {                                                                
3231         super.onTrimMemory(level);                                                                       
3232         if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                        
3233             // The widget preview db can result in holding onto over                                     
3234             // 3MB of memory for caching which isn't necessary.                                          
3235             SQLiteDatabase.releaseMemory();                                                              
3236             // This clears all widget bitmaps from the widget tray                                       
3237             // TODO(hyunyoungs)                                                                          
3238         }                                                                                                
3239         if (mLauncherCallbacks != null) {                                                                
3240             mLauncherCallbacks.onTrimMemory(level);                                                      
3241         }                                                                                                
3242     }                                                                                                    
3243                                                                                                          
3244     @Override                                                                                            
3245     public void onStateTransitionHideSearchBar() {                                                       
3246                     // Hide the search bar                                                               
3247         if (mSearchDropTargetBar != null) {                                                              
3248             /* animated */                                                                               
3249             mSearchDropTargetBar.hideSearchBar(false);                                                   
3250         }                                                                                                
3251     }                                                                                                    
3252                                                                                                          
3253     protected void showWorkspace(boolean animated) {                                                     
3254         showWorkspace(animated, null);                                                                   
3255     }                                                                                                    
3256                                                                                                          
3257     void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                  
3258         boolean changed = (mState != State.WORKSPACE) || (mWorkspace.getState() != Workspace.State.NORMAL🔵
3259         if (changed) {                                                                                   
3260             boolean wasInSpringLoadedMode = mState != State.WORKSPACE;                                   
3261             mWorkspace.setVisibility(View.VISIBLE);                                                      
3262             mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL, animated,🔵
3263             // Show the search bar (only animate if we were showing the drop target bar in spring        
3264             // loaded mode)                                                                              
3265             if (mSearchDropTargetBar != null) {                                                          
3266                 mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                   
3267             }                                                                                            
3268             // Set focus to the AppsCustomize button                                                     
3269             if (mAllAppsButton != null) {                                                                
3270                 mAllAppsButton.requestFocus();                                                           
3271             }                                                                                            
3272         }                                                                                                
3273         // Change the state *after* we've called all the transition code                                 
3274         mState = State.WORKSPACE;                                                                        
3275         // Resume the auto-advance of widgets                                                            
3276         mUserPresent = true;                                                                             
3277         updateAutoAdvanceState();                                                                        
3278         if (changed) {                                                                                   
3279             // Send an accessibility event to announce the context change                                
3280             getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGE🔵
3281             onWorkspaceShown(animated);                                                                  
3282         }                                                                                                
3283     }                                                                                                    
3284                                                                                                          
3285     void showOverviewMode(boolean animated) {                                                            
3286         mWorkspace.setVisibility(View.VISIBLE);                                                          
3287                 /* onCompleteRunnable */                                                                 
3288         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW, animated, n🔵
3289         mState = State.WORKSPACE;                                                                        
3290         onWorkspaceShown(animated);                                                                      
3291     }                                                                                                    
3292                                                                                                          
3293     public void onWorkspaceShown(boolean animated) {                                                     
3294     }                                                                                                    
3295                                                                                                          
3296     /**                                                                                                  
3297      * Shows the apps view.                                                                              
3298      */                                                                                                  
3299     void showAppsView(boolean animated, boolean resetListToTop) {                                        
3300         if (resetListToTop) {                                                                            
3301             mAppsView.scrollToTop();                                                                     
3302         }                                                                                                
3303         showAppsOrWidgets(animated, State.APPS);                                                         
3304     }                                                                                                    
3305                                                                                                          
3306     /**                                                                                                  
3307      * Shows the widgets view.                                                                           
3308      */                                                                                                  
3309     void showWidgetsView(boolean animated, boolean resetPageToZero) {                                    
3310         Log.d(TAG, (("showWidgetsView:" + animated) + " resetPageToZero:") + resetPageToZero);           
3311         if (resetPageToZero) {                                                                           
3312             mWidgetsView.scrollToTop();                                                                  
3313         }                                                                                                
3314         showAppsOrWidgets(animated, State.WIDGETS);                                                      
3315         mWidgetsView.post(new Runnable() {                                                               
3316             @Override                                                                                    
3317             public void run() {                                                                          
3318                 mWidgetsView.requestFocus();                                                             
3319             }                                                                                            
3320         });                                                                                              
3321     }                                                                                                    
3322                                                                                                          
3323     /**                                                                                                  
3324      * Sets up the transition to show the apps/widgets view.                                             
3325      */                                                                                                  
3326     private void showAppsOrWidgets(boolean animated, State toState) {                                    
3327         if (mState != State.WORKSPACE) {                                                                 
3328             return;                                                                                      
3329         }                                                                                                
3330         if ((toState != State.APPS) && (toState != State.WIDGETS)) {                                     
3331             return;                                                                                      
3332         }                                                                                                
3333         if (toState == State.APPS) {                                                                     
3334             mStateTransitionAnimation.startAnimationToAllApps(animated);                                 
3335             if (mLauncherCallbacks != null) {                                                            
3336                 mLauncherCallbacks.onAllAppsShown();                                                     
3337             }                                                                                            
3338         } else {                                                                                         
3339             mStateTransitionAnimation.startAnimationToWidgets(animated);                                 
3340         }                                                                                                
3341         // Change the state *after* we've called all the transition code                                 
3342         mState = toState;                                                                                
3343         // Pause the auto-advance of widgets until we are out of AllApps                                 
3344         mUserPresent = false;                                                                            
3345         updateAutoAdvanceState();                                                                        
3346         closeFolder();                                                                                   
3347         // Send an accessibility event to announce the context change                                    
3348         getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 
3349     }                                                                                                    
3350                                                                                                          
3351     public void enterSpringLoadedDragMode() {                                                            
3352         Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s", mState.name()));                
3353         if (((mState == State.WORKSPACE) || (mState == State.APPS_SPRING_LOADED)) || (mState == State.WID🔵
3354             return;                                                                                      
3355         }                                                                                                
3356                 /* animated */                                                                           
3357                 /* onCompleteRunnable */                                                                 
3358         mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED, true, 🔵
3359         mState = (isAppsViewVisible()) ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;         
3360     }                                                                                                    
3361                                                                                                          
3362     public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay, final Runnable o🔵
3363         if ((mState != State.APPS_SPRING_LOADED) && (mState != State.WIDGETS_SPRING_LOADED)) {           
3364             return;                                                                                      
3365         }                                                                                                
3366         mHandler.postDelayed(new Runnable() {                                                            
3367             @Override                                                                                    
3368             public void run() {                                                                          
3369                 if (successfulDrop) {                                                                    
3370                     // TODO(hyunyoungs): verify if this hack is still needed, if not, delete.            
3371                     //                                                                                   
3372                     // Before we show workspace, hide all apps again because                             
3373                     // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should          
3374                     // clean up our state transition functions                                           
3375                     mWidgetsView.setVisibility(View.GONE);                                               
3376                     showWorkspace(true, onCompleteRunnable);                                             
3377                 } else {                                                                                 
3378                     exitSpringLoadedDragMode();                                                          
3379                 }                                                                                        
3380             }                                                                                            
3381         }, delay);                                                                                       
3382     }                                                                                                    
3383                                                                                                          
3384     void exitSpringLoadedDragMode() {                                                                    
3385         if (mState == State.APPS_SPRING_LOADED) {                                                        
3386             /* animated */                                                                               
3387             mStateTransitionAnimation.startAnimationToAllApps(true);                                     
3388             mState = State.APPS;                                                                         
3389         } else if (mState == State.WIDGETS_SPRING_LOADED) {                                              
3390             /* animated */                                                                               
3391             mStateTransitionAnimation.startAnimationToWidgets(true);                                     
3392             mState = State.WIDGETS;                                                                      
3393         }                                                                                                
3394         // Otherwise, we are not in spring loaded mode, so don't do anything.                            
3395     }                                                                                                    
3396                                                                                                          
3397     void lockAllApps() {                                                                                 
3398         // TODO                                                                                          
3399     }                                                                                                    
3400                                                                                                          
3401     void unlockAllApps() {                                                                               
3402         // TODO                                                                                          
3403     }                                                                                                    
3404                                                                                                          
3405     protected void disableVoiceButtonProxy(boolean disable) {                                            
3406         // NO-OP                                                                                         
3407     }                                                                                                    
3408                                                                                                          
3409     public View getOrCreateQsbBar() {                                                                    
3410         if ((mLauncherCallbacks != null) && mLauncherCallbacks.providesSearch()) {                       
3411             return mLauncherCallbacks.getQsbBar();                                                       
3412         }                                                                                                
3413         if (mQsb == null) {                                                                              
3414             AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);              
3415             if (searchProvider == null) {                                                                
3416                 return null;                                                                             
3417             }                                                                                            
3418             Bundle opts = new Bundle();                                                                  
3419             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, AppWidgetProviderInfo.WIDGET_CAT🔵
3420             SharedPreferences sp = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(), MODE_🔵
3421             int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                 
3422             AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);             
3423             if (((!searchProvider.provider.flattenToString().equals(sp.getString(QSB_WIDGET_PROVIDER, nul🔵
3424                 // A valid widget is not already bound.                                                  
3425                 if (widgetId > (-1)) {                                                                   
3426                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3427                     widgetId = -1;                                                                       
3428                 }                                                                                        
3429                 // Try to bind a new widget                                                              
3430                 widgetId = mAppWidgetHost.allocateAppWidgetId();                                         
3431                 if (!AppWidgetManagerCompat.getInstance(this).bindAppWidgetIdIfAllowed(widgetId, searchPr🔵
3432                     mAppWidgetHost.deleteAppWidgetId(widgetId);                                          
3433                     widgetId = -1;                                                                       
3434                 }                                                                                        
3435                 sp.edit().putInt(QSB_WIDGET_ID, widgetId).putString(QSB_WIDGET_PROVIDER, searchProvider.p🔵
3436             }                                                                                            
3437             if (widgetId != (-1)) {                                                                      
3438                 mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                        
3439                 mQsb.updateAppWidgetOptions(opts);                                                       
3440                 mQsb.setPadding(0, 0, 0, 0);                                                             
3441                 mSearchDropTargetBar.addView(mQsb);                                                      
3442                 mSearchDropTargetBar.setQsbSearchBar(mQsb);                                              
3443             }                                                                                            
3444         }                                                                                                
3445         return mQsb;                                                                                     
3446     }                                                                                                    
3447                                                                                                          
3448     private void reinflateQSBIfNecessary() {                                                             
3449         if ((mQsb instanceof LauncherAppWidgetHostView) && ((LauncherAppWidgetHostView) (mQsb)).isReinfla🔵
3450             mSearchDropTargetBar.removeView(mQsb);                                                       
3451             mQsb = null;                                                                                 
3452             mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                   
3453         }                                                                                                
3454     }                                                                                                    
3455                                                                                                          
3456     @Override                                                                                            
3457     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                        
3458         final boolean result = super.dispatchPopulateAccessibilityEvent(event);                          
3459         final List<CharSequence> text = event.getText();                                                 
3460         text.clear();                                                                                    
3461         // Populate event with a fake title based on the current state.                                  
3462         if (mState == State.APPS) {                                                                      
3463             text.add("Apps");                                                                            
3464         } else if (mState == State.WIDGETS) {                                                            
3465             text.add("Widgets");                                                                         
3466         } else {                                                                                         
3467             text.add(getString(R.string.all_apps_home_button_label));                                    
3468         }                                                                                                
3469         return result;                                                                                   
3470     }                                                                                                    
3471                                                                                                          
3472     /**                                                                                                  
3473      * Receives notifications when system dialogs are to be closed.                                      
3474      */                                                                                                  
3475     @Thunk                                                                                               
3476     class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                   
3477         @Override                                                                                        
3478         public void onReceive(Context context, Intent intent) {                                          
3479             closeSystemDialogs();                                                                        
3480         }                                                                                                
3481     }                                                                                                    
3482                                                                                                          
3483     /**                                                                                                  
3484      * Receives notifications whenever the appwidgets are reset.                                         
3485      */                                                                                                  
3486     private class AppWidgetResetObserver extends ContentObserver {                                       
3487         public AppWidgetResetObserver() {                                                                
3488             super(new Handler());                                                                        
3489         }                                                                                                
3490                                                                                                          
3491         @Override                                                                                        
3492         public void onChange(boolean selfChange) {                                                       
3493             onAppWidgetReset();                                                                          
3494         }                                                                                                
3495     }                                                                                                    
3496                                                                                                          
3497     /**                                                                                                  
3498      * If the activity is currently paused, signal that we need to run the passed Runnable               
3499      * in onResume.                                                                                      
3500      *                                                                                                   
3501      * This needs to be called from incoming places where resources might have been loaded               
3502      * while we are paused.  That is becaues the Configuration might be wrong                            
3503      * when we're not running, and if it comes back to what it was when we                               
3504      * were paused, we are not restarted.                                                                
3505      *                                                                                                   
3506      * Implementation of the method from LauncherModel.Callbacks.                                        
3507      *                                                                                                   
3508      * @return true if we are currently paused.  The caller might be able to                             
3509      * skip some work in that case since we will come back again.                                        
3510      */                                                                                                  
3511     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                     
3512         if (mPaused) {                                                                                   
3513             Log.i(TAG, "Deferring update until onResume");                                               
3514             if (deletePreviousRunnables) {                                                               
3515                 while (mBindOnResumeCallbacks.remove(run)) {                                             
3516                 }                                                                                        
3517             }                                                                                            
3518             mBindOnResumeCallbacks.add(run);                                                             
3519             return true;                                                                                 
3520         } else {                                                                                         
3521             return false;                                                                                
3522         }                                                                                                
3523     }                                                                                                    
3524                                                                                                          
3525     private boolean waitUntilResume(Runnable run) {                                                      
3526         return waitUntilResume(run, false);                                                              
3527     }                                                                                                    
3528                                                                                                          
3529     public void addOnResumeCallback(Runnable run) {                                                      
3530         mOnResumeCallbacks.add(run);                                                                     
3531     }                                                                                                    
3532                                                                                                          
3533     /**                                                                                                  
3534      * If the activity is currently paused, signal that we need to re-run the loader                     
3535      * in onResume.                                                                                      
3536      *                                                                                                   
3537      * This needs to be called from incoming places where resources might have been loaded               
3538      * while we are paused.  That is becaues the Configuration might be wrong                            
3539      * when we're not running, and if it comes back to what it was when we                               
3540      * were paused, we are not restarted.                                                                
3541      *                                                                                                   
3542      * Implementation of the method from LauncherModel.Callbacks.                                        
3543      *                                                                                                   
3544      * @return true if we are currently paused.  The caller might be able to                             
3545      * skip some work in that case since we will come back again.                                        
3546      */                                                                                                  
3547     public boolean setLoadOnResume() {                                                                   
3548         if (mPaused) {                                                                                   
3549             Log.i(TAG, "setLoadOnResume");                                                               
3550             mOnResumeNeedsLoad = true;                                                                   
3551             return true;                                                                                 
3552         } else {                                                                                         
3553             return false;                                                                                
3554         }                                                                                                
3555     }                                                                                                    
3556                                                                                                          
3557     /**                                                                                                  
3558      * Implementation of the method from LauncherModel.Callbacks.                                        
3559      */                                                                                                  
3560     public int getCurrentWorkspaceScreen() {                                                             
3561         if (mWorkspace != null) {                                                                        
3562             return mWorkspace.getCurrentPage();                                                          
3563         } else {                                                                                         
3564             return SCREEN_COUNT / 2;                                                                     
3565         }                                                                                                
3566     }                                                                                                    
3567                                                                                                          
3568     /**                                                                                                  
3569      * Refreshes the shortcuts shown on the workspace.                                                   
3570      *                                                                                                   
3571      * Implementation of the method from LauncherModel.Callbacks.                                        
3572      */                                                                                                  
3573     public void startBinding() {                                                                         
3574         setWorkspaceLoading(true);                                                                       
3575                                                                                                          
3576         // If we're starting binding all over again, clear any bind calls we'd postponed in              
3577         // the past (see waitUntilResume) -- we don't need them since we're starting binding             
3578         // from scratch again                                                                            
3579         mBindOnResumeCallbacks.clear();                                                                  
3580                                                                                                          
3581         // Clear the workspace because it's going to be rebound                                          
3582         mWorkspace.clearDropTargets();                                                                   
3583         mWorkspace.removeAllWorkspaceScreens();                                                          
3584                                                                                                          
3585         mWidgetsToAdvance.clear();                                                                       
3586         if (mHotseat != null) {                                                                          
3587             mHotseat.resetLayout();                                                                      
3588         }                                                                                                
3589     }                                                                                                    
3590                                                                                                          
3591     @Override                                                                                            
3592     public void bindScreens(ArrayList<Long> orderedScreenIds) {                                          
3593         bindAddScreens(orderedScreenIds);                                                                
3594                                                                                                          
3595         // If there are no screens, we need to have an empty screen                                      
3596         if (orderedScreenIds.size() == 0) {                                                              
3597             mWorkspace.addExtraEmptyScreen();                                                            
3598         }                                                                                                
3599                                                                                                          
3600         // Create the custom content page (this call updates mDefaultScreen which calls                  
3601         // setCurrentPage() so ensure that all pages are added before calling this).                     
3602         if (hasCustomContentToLeft()) {                                                                  
3603             mWorkspace.createCustomContentContainer();                                                   
3604             populateCustomContentContainer();                                                            
3605         }                                                                                                
3606     }                                                                                                    
3607                                                                                                          
3608     @Override                                                                                            
3609     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                       
3610         // Log to disk                                                                                   
3611         Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                   
3612         Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                     
3613                 TextUtils.join(", ", orderedScreenIds), true);                                           
3614         int count = orderedScreenIds.size();                                                             
3615         for (int i = 0; i < count; i++) {                                                                
3616             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));               
3617         }                                                                                                
3618     }                                                                                                    
3619                                                                                                          
3620     @Override                                                                                            
3621     public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                  
3622             final long screenId, final int[] cell, final int spanX, final int spanY) {                   
3623         showWorkspace(true, new Runnable() {                                                             
3624                                                                                                          
3625             @Override                                                                                    
3626             public void run() {                                                                          
3627                 mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                     
3628                 addPendingItem(info, container, screenId, cell, spanX, spanY);                           
3629             }                                                                                            
3630         });                                                                                              
3631     }                                                                                                    
3632                                                                                                          
3633     private boolean shouldShowWeightWatcher() {                                                          
3634         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3635         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3636         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                  
3637                                                                                                          
3638         return show;                                                                                     
3639     }                                                                                                    
3640                                                                                                          
3641     private void toggleShowWeightWatcher() {                                                             
3642         String spKey = LauncherAppState.getSharedPreferencesKey();                                       
3643         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                        
3644         boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                         
3645                                                                                                          
3646         show = !show;                                                                                    
3647                                                                                                          
3648         SharedPreferences.Editor editor = sp.edit();                                                     
3649         editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                    
3650         editor.commit();                                                                                 
3651                                                                                                          
3652         if (mWeightWatcher != null) {                                                                    
3653             mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                               
3654         }                                                                                                
3655     }                                                                                                    
3656                                                                                                          
3657     public void bindAppsAdded(final ArrayList<Long> newScreens, final ArrayList<ItemInfo> addNotAnimated,🔵
3658         Runnable r = new Runnable() {                                                                    
3659             public void run() {                                                                          
3660                 bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                       
3661             }                                                                                            
3662         };                                                                                               
3663         if (waitUntilResume(r)) {                                                                        
3664             return;                                                                                      
3665         }                                                                                                
3666         // Add the new screens                                                                           
3667         if (newScreens != null) {                                                                        
3668             bindAddScreens(newScreens);                                                                  
3669         }                                                                                                
3670         // We add the items without animation on non-visible pages, and with                             
3671         // animations on the new page (which we will try and snap to).                                   
3672         if ((addNotAnimated != null) && (!addNotAnimated.isEmpty())) {                                   
3673             bindItems(addNotAnimated, 0, addNotAnimated.size(), false);                                  
3674         }                                                                                                
3675         if ((addAnimated != null) && (!addAnimated.isEmpty())) {                                         
3676             bindItems(addAnimated, 0, addAnimated.size(), true);                                         
3677         }                                                                                                
3678         // Remove the extra empty screen                                                                 
3679         mWorkspace.removeExtraEmptyScreen(false, false);                                                 
3680         if ((addedApps != null) && (mAppsView != null)) {                                                
3681             mAppsView.addApps(addedApps);                                                                
3682         }                                                                                                
3683     }                                                                                                    
3684                                                                                                          
3685     /**                                                                                                  
3686      * Bind the items start-end from the list.                                                           
3687      *                                                                                                   
3688      * Implementation of the method from LauncherModel.Callbacks.                                        
3689      */                                                                                                  
3690     public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,           
3691                           final boolean forceAnimateIcons) {                                             
3692         Runnable r = new Runnable() {                                                                    
3693             public void run() {                                                                          
3694                 bindItems(shortcuts, start, end, forceAnimateIcons);                                     
3695             }                                                                                            
3696         };                                                                                               
3697         if (waitUntilResume(r)) {                                                                        
3698             return;                                                                                      
3699         }                                                                                                
3700                                                                                                          
3701         // Get the list of added shortcuts and intersect them with the set of shortcuts here             
3702         final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                  
3703         final Collection<Animator> bounceAnims = new ArrayList<Animator>();                              
3704         final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                      
3705         Workspace workspace = mWorkspace;                                                                
3706         long newShortcutsScreenId = -1;                                                                  
3707         for (int i = start; i < end; i++) {                                                              
3708             final ItemInfo item = shortcuts.get(i);                                                      
3709                                                                                                          
3710             // Short circuit if we are loading dock items for a configuration which has no dock          
3711             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                        
3712                     mHotseat == null) {                                                                  
3713                 continue;                                                                                
3714             }                                                                                            
3715                                                                                                          
3716             switch (item.itemType) {                                                                     
3717                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                   
3718                 case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                      
3719                     ShortcutInfo info = (ShortcutInfo) item;                                             
3720                     View shortcut = createShortcut(info);                                                
3721                                                                                                          
3722                     /*                                                                                   
3723                      * TODO: FIX collision case                                                          
3724                      */                                                                                  
3725                     if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                
3726                         CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                       
3727                         if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                       
3728                             View v = cl.getChildAt(item.cellX, item.cellY);                              
3729                             Object tag = v.getTag();                                                     
3730                             String desc = "Collision while binding workspace item: " + item              
3731                                     + ". Collides with " + tag;                                          
3732                             if (LauncherAppState.isDogfoodBuild()) {                                     
3733                                 throw (new RuntimeException(desc));                                      
3734                             } else {                                                                     
3735                                 Log.d(TAG, desc);                                                        
3736                             }                                                                            
3737                         }                                                                                
3738                     }                                                                                    
3739                                                                                                          
3740                     workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,   
3741                             item.cellY, 1, 1);                                                           
3742                     if (animateIcons) {                                                                  
3743                         // Animate all the applications up now                                           
3744                         shortcut.setAlpha(0f);                                                           
3745                         shortcut.setScaleX(0f);                                                          
3746                         shortcut.setScaleY(0f);                                                          
3747                         bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                       
3748                         newShortcutsScreenId = item.screenId;                                            
3749                     }                                                                                    
3750                     break;                                                                               
3751                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                        
3752                     FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                
3753                             (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                
3754                             (FolderInfo) item, mIconCache);                                              
3755                     workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,  
3756                             item.cellY, 1, 1);                                                           
3757                     break;                                                                               
3758                 default:                                                                                 
3759                     throw new RuntimeException("Invalid Item Type");                                     
3760             }                                                                                            
3761         }                                                                                                
3762                                                                                                          
3763         if (animateIcons) {                                                                              
3764             // Animate to the correct page                                                               
3765             if (newShortcutsScreenId > -1) {                                                             
3766                 long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());     
3767                 final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);     
3768                 final Runnable startBounceAnimRunnable = new Runnable() {                                
3769                     public void run() {                                                                  
3770                         anim.playTogether(bounceAnims);                                                  
3771                         anim.start();                                                                    
3772                     }                                                                                    
3773                 };                                                                                       
3774                 if (newShortcutsScreenId != currentScreenId) {                                           
3775                     // We post the animation slightly delayed to prevent slowdowns                       
3776                     // when we are loading right after we return to launcher.                            
3777                     mWorkspace.postDelayed(new Runnable() {                                              
3778                         public void run() {                                                              
3779                             if (mWorkspace != null) {                                                    
3780                                 mWorkspace.snapToPage(newScreenIndex);                                   
3781                                 mWorkspace.postDelayed(startBounceAnimRunnable,                          
3782                                         NEW_APPS_ANIMATION_DELAY);                                       
3783                             }                                                                            
3784                         }                                                                                
3785                     }, NEW_APPS_PAGE_MOVE_DELAY);                                                        
3786                 } else {                                                                                 
3787                     mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);           
3788                 }                                                                                        
3789             }                                                                                            
3790         }                                                                                                
3791         workspace.requestLayout();                                                                       
3792     }                                                                                                    
3793                                                                                                          
3794     /**                                                                                                  
3795      * Implementation of the method from LauncherModel.Callbacks.                                        
3796      */                                                                                                  
3797     public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                   
3798         Runnable r = new Runnable() {                                                                    
3799             public void run() {                                                                          
3800                 bindFolders(folders);                                                                    
3801             }                                                                                            
3802         };                                                                                               
3803         if (waitUntilResume(r)) {                                                                        
3804             return;                                                                                      
3805         }                                                                                                
3806         sFolders.clear();                                                                                
3807         sFolders.putAll(folders);                                                                        
3808     }                                                                                                    
3809                                                                                                          
3810     /**                                                                                                  
3811      * Add the views for a widget to the workspace.                                                      
3812      *                                                                                                   
3813      * Implementation of the method from LauncherModel.Callbacks.                                        
3814      */                                                                                                  
3815     public void bindAppWidget(final LauncherAppWidgetInfo item) {                                        
3816         Runnable r = new Runnable() {                                                                    
3817             public void run() {                                                                          
3818                 bindAppWidget(item);                                                                     
3819             }                                                                                            
3820         };                                                                                               
3821         if (waitUntilResume(r)) {                                                                        
3822             return;                                                                                      
3823         }                                                                                                
3824         final long start = (DEBUG_WIDGETS) ? SystemClock.uptimeMillis() : 0;                             
3825         if (DEBUG_WIDGETS) {                                                                             
3826             Log.d(TAG, "bindAppWidget: " + item);                                                        
3827         }                                                                                                
3828         final Workspace workspace = mWorkspace;                                                          
3829         LauncherAppWidgetProviderInfo appWidgetInfo = LauncherModel.getProviderInfo(this, item.providerNa🔵
3830         if (((!mIsSafeModeEnabled) && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READ🔵
3831             if (appWidgetInfo == null) {                                                                 
3832                 if (DEBUG_WIDGETS) {                                                                     
3833                     Log.d(TAG, ((("Removing restored widget: id=" + item.appWidgetId) + " belongs to comp🔵
3834                 }                                                                                        
3835                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3836                 return;                                                                                  
3837             }                                                                                            
3838             // Note: This assumes that the id remap broadcast is received before this step.              
3839             // If that is not the case, the id remap will be ignored and user may see the                
3840             // click to setup view.                                                                      
3841             PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);            
3842             pendingInfo.spanX = item.spanX;                                                              
3843             pendingInfo.spanY = item.spanY;                                                              
3844             pendingInfo.minSpanX = item.minSpanX;                                                        
3845             pendingInfo.minSpanY = item.minSpanY;                                                        
3846             Bundle options = null;                                                                       
3847             //        AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);              
3848             int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                      
3849             boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(newWidgetId, appWidgetInfo, opti🔵
3850             // TODO consider showing a permission dialog when the widget is clicked.                     
3851             if (!success) {                                                                              
3852                 mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                           
3853                 if (DEBUG_WIDGETS) {                                                                     
3854                     Log.d(TAG, ((("Removing restored widget: id=" + item.appWidgetId) + " belongs to comp🔵
3855                 }                                                                                        
3856                 LauncherModel.deleteItemFromDatabase(this, item);                                        
3857                 return;                                                                                  
3858             }                                                                                            
3859             item.appWidgetId = newWidgetId;                                                              
3860             // If the widget has a configure activity, it is still needs to set it up, otherwise         
3861             // the widget is ready to go.                                                                
3862             item.restoreStatus = (appWidgetInfo.configure == null) ? LauncherAppWidgetInfo.RESTORE_COMPLE🔵
3863             LauncherModel.updateItemInDatabase(this, item);                                              
3864         }                                                                                                
3865         if ((!mIsSafeModeEnabled) && (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED)) {  
3866             final int appWidgetId = item.appWidgetId;                                                    
3867             if (DEBUG_WIDGETS) {                                                                         
3868                 Log.d(TAG, (("bindAppWidget: id=" + item.appWidgetId) + " belongs to component ") + appWi🔵
3869             }                                                                                            
3870             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                 
3871         } else {                                                                                         
3872             appWidgetInfo = null;                                                                        
3873             PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item, mIsSafeModeEnabled);
3874             view.updateIcon(mIconCache);                                                                 
3875             item.hostView = view;                                                                        
3876             item.hostView.updateAppWidget(null);                                                         
3877             item.hostView.setOnClickListener(this);                                                      
3878         }                                                                                                
3879         item.hostView.setTag(item);                                                                      
3880         item.onBindAppWidget(this);                                                                      
3881         workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX, item.cellY, item.🔵
3882         if (!item.isCustomWidget()) {                                                                    
3883             addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                
3884         }                                                                                                
3885         workspace.requestLayout();                                                                       
3886         if (DEBUG_WIDGETS) {                                                                             
3887             Log.d(TAG, ((("bound widget id=" + item.appWidgetId) + " in ") + (SystemClock.uptimeMillis() 🔵
3888         }                                                                                                
3889     }                                                                                                    
3890                                                                                                          
3891     /**                                                                                                  
3892      * Restores a pending widget.                                                                        
3893      *                                                                                                   
3894      * @param appWidgetId The app widget id                                                              
3895      * @param cellInfo The position on screen where to create the widget.                                
3896      */                                                                                                  
3897     private void completeRestoreAppWidget(final int appWidgetId) {                                       
3898         LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                
3899         if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                             
3900             Log.e(TAG, "Widget update called, when the widget no longer exists.");                       
3901             return;                                                                                      
3902         }                                                                                                
3903                                                                                                          
3904         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                              
3905         info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                    
3906                                                                                                          
3907         mWorkspace.reinflateWidgetsIfNecessary();                                                        
3908         LauncherModel.updateItemInDatabase(this, info);                                                  
3909     }                                                                                                    
3910                                                                                                          
3911     public void onPageBoundSynchronously(int page) {                                                     
3912         mSynchronouslyBoundPages.add(page);                                                              
3913     }                                                                                                    
3914                                                                                                          
3915     /**                                                                                                  
3916      * Callback saying that there aren't any more items to bind.                                         
3917      *                                                                                                   
3918      * Implementation of the method from LauncherModel.Callbacks.                                        
3919      */                                                                                                  
3920     public void finishBindingItems() {                                                                   
3921         Runnable r = new Runnable() {                                                                    
3922             public void run() {                                                                          
3923                 finishBindingItems();                                                                    
3924             }                                                                                            
3925         };                                                                                               
3926         if (waitUntilResume(r)) {                                                                        
3927             return;                                                                                      
3928         }                                                                                                
3929         if (mSavedState != null) {                                                                       
3930             if (!mWorkspace.hasFocus()) {                                                                
3931                 mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                       
3932             }                                                                                            
3933             mSavedState = null;                                                                          
3934         }                                                                                                
3935         mWorkspace.restoreInstanceStateForRemainingPages();                                              
3936         setWorkspaceLoading(false);                                                                      
3937         sendLoadingCompleteBroadcastIfNecessary();                                                       
3938         // If we received the result of any pending adds while the loader was running (e.g. the          
3939         // widget configuration forced an orientation change), process them now.                         
3940         if (sPendingAddItem != null) {                                                                   
3941             final long screenId = completeAdd(sPendingAddItem);                                          
3942             // TODO: this moves the user to the page where the pending item was added. Ideally,          
3943             // the screen would be guaranteed to exist after bind, and the page would be set through     
3944             // the workspace restore process.                                                            
3945             mWorkspace.post(new Runnable() {                                                             
3946                 @Override                                                                                
3947                 public void run() {                                                                      
3948                     mWorkspace.snapToScreenId(screenId);                                                 
3949                 }                                                                                        
3950             });                                                                                          
3951             sPendingAddItem = null;                                                                      
3952         }                                                                                                
3953         PackageInstallerCompat.getInstance(this).onFinishBind();                                         
3954         if (mLauncherCallbacks != null) {                                                                
3955             mLauncherCallbacks.finishBindingItems(false);                                                
3956         }                                                                                                
3957     }                                                                                                    
3958                                                                                                          
3959     private void sendLoadingCompleteBroadcastIfNecessary() {                                             
3960         if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                      
3961             String permission =                                                                          
3962                     getResources().getString(R.string.receive_first_load_broadcast_permission);          
3963             Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                      
3964             sendBroadcast(intent, permission);                                                           
3965             SharedPreferences.Editor editor = mSharedPrefs.edit();                                       
3966             editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                
3967             editor.apply();                                                                              
3968         }                                                                                                
3969     }                                                                                                    
3970                                                                                                          
3971     public boolean isAllAppsButtonRank(int rank) {                                                       
3972         if (mHotseat != null) {                                                                          
3973             return mHotseat.isAllAppsButtonRank(rank);                                                   
3974         }                                                                                                
3975         return false;                                                                                    
3976     }                                                                                                    
3977                                                                                                          
3978     private boolean canRunNewAppsAnimation() {                                                           
3979         long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                 
3980         return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                              
3981     }                                                                                                    
3982                                                                                                          
3983     private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                   
3984         ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                           
3985                 PropertyValuesHolder.ofFloat("alpha", 1f),                                               
3986                 PropertyValuesHolder.ofFloat("scaleX", 1f),                                              
3987                 PropertyValuesHolder.ofFloat("scaleY", 1f));                                             
3988         bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                    
3989         bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                
3990         bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                         
3991         return bounceAnim;                                                                               
3992     }                                                                                                    
3993                                                                                                          
3994     public boolean useVerticalBarLayout() {                                                              
3995         return LauncherAppState.getInstance().getDynamicGrid().                                          
3996                 getDeviceProfile().isVerticalBarLayout();                                                
3997     }                                                                                                    
3998                                                                                                          
3999     protected Rect getSearchBarBounds() {                                                                
4000         return LauncherAppState.getInstance().getDynamicGrid().                                          
4001                 getDeviceProfile().getSearchBarBounds();                                                 
4002     }                                                                                                    
4003                                                                                                          
4004     public void bindSearchablesChanged() {                                                               
4005         if (mSearchDropTargetBar == null) {                                                              
4006             return;                                                                                      
4007         }                                                                                                
4008         if (mQsb != null) {                                                                              
4009             mSearchDropTargetBar.removeView(mQsb);                                                       
4010             mQsb = null;                                                                                 
4011         }                                                                                                
4012         mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                       
4013     }                                                                                                    
4014                                                                                                          
4015     /**                                                                                                  
4016      * Add the icons for all apps.                                                                       
4017      *                                                                                                   
4018      * Implementation of the method from LauncherModel.Callbacks.                                        
4019      */                                                                                                  
4020     public void bindAllApplications(final ArrayList<AppInfo> apps) {                                     
4021         if (mAppsView != null) {                                                                         
4022             mAppsView.setApps(apps);                                                                     
4023         }                                                                                                
4024         if (mWidgetsView != null) {                                                                      
4025             mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false), getPackageMa🔵
4026         }                                                                                                
4027         if (mLauncherCallbacks != null) {                                                                
4028             mLauncherCallbacks.bindAllApplications(apps);                                                
4029         }                                                                                                
4030     }                                                                                                    
4031                                                                                                          
4032     /**                                                                                                  
4033      * A package was updated.                                                                            
4034      *                                                                                                   
4035      * Implementation of the method from LauncherModel.Callbacks.                                        
4036      */                                                                                                  
4037     public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                         
4038         Runnable r = new Runnable() {                                                                    
4039             public void run() {                                                                          
4040                 bindAppsUpdated(apps);                                                                   
4041             }                                                                                            
4042         };                                                                                               
4043         if (waitUntilResume(r)) {                                                                        
4044             return;                                                                                      
4045         }                                                                                                
4046         if (mAppsView != null) {                                                                         
4047             mAppsView.updateApps(apps);                                                                  
4048         }                                                                                                
4049     }                                                                                                    
4050                                                                                                          
4051     @Override                                                                                            
4052     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                    
4053         Runnable r = new Runnable() {                                                                    
4054             public void run() {                                                                          
4055                 bindWidgetsRestored(widgets);                                                            
4056             }                                                                                            
4057         };                                                                                               
4058         if (waitUntilResume(r)) {                                                                        
4059             return;                                                                                      
4060         }                                                                                                
4061         mWorkspace.widgetsRestored(widgets);                                                             
4062     }                                                                                                    
4063                                                                                                          
4064     /**                                                                                                  
4065      * Some shortcuts were updated in the background.                                                    
4066      *                                                                                                   
4067      * Implementation of the method from LauncherModel.Callbacks.                                        
4068      */                                                                                                  
4069     @Override                                                                                            
4070     public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                              
4071             final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                        
4072         Runnable r = new Runnable() {                                                                    
4073             public void run() {                                                                          
4074                 bindShortcutsChanged(updated, removed, user);                                            
4075             }                                                                                            
4076         };                                                                                               
4077         if (waitUntilResume(r)) {                                                                        
4078             return;                                                                                      
4079         }                                                                                                
4080                                                                                                          
4081         if (!updated.isEmpty()) {                                                                        
4082             mWorkspace.updateShortcuts(updated);                                                         
4083         }                                                                                                
4084                                                                                                          
4085         if (!removed.isEmpty()) {                                                                        
4086             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4087             for (ShortcutInfo si : removed) {                                                            
4088                 removedComponents.add(si.getTargetComponent());                                          
4089             }                                                                                            
4090             mWorkspace.removeItemsByComponentName(removedComponents, user);                              
4091             // Notify the drag controller                                                                
4092             mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                   
4093         }                                                                                                
4094     }                                                                                                    
4095                                                                                                          
4096     /**                                                                                                  
4097      * Update the state of a package, typically related to install state.                                
4098      *                                                                                                   
4099      * Implementation of the method from LauncherModel.Callbacks.                                        
4100      */                                                                                                  
4101     @Override                                                                                            
4102     public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                          
4103         if (mWorkspace != null) {                                                                        
4104             mWorkspace.updatePackageState(installInfo);                                                  
4105         }                                                                                                
4106     }                                                                                                    
4107                                                                                                          
4108     /**                                                                                                  
4109      * Update the label and icon of all the icons in a package                                           
4110      *                                                                                                   
4111      * Implementation of the method from LauncherModel.Callbacks.                                        
4112      */                                                                                                  
4113     @Override                                                                                            
4114     public void updatePackageBadge(String packageName) {                                                 
4115         if (mWorkspace != null) {                                                                        
4116             mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                 
4117         }                                                                                                
4118     }                                                                                                    
4119                                                                                                          
4120     /**                                                                                                  
4121      * A package was uninstalled.  We take both the super set of packageNames                            
4122      * in addition to specific applications to remove, the reason being that                             
4123      * this can be called when a package is updated as well.  In that scenario,                          
4124      * we only remove specific components from the workspace, where as                                   
4125      * package-removal should clear all items by package name.                                           
4126      *                                                                                                   
4127      * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.      
4128      * Implementation of the method from LauncherModel.Callbacks.                                        
4129      */                                                                                                  
4130     @Override                                                                                            
4131     public void bindComponentsRemoved(final ArrayList<String> packageNames, final ArrayList<AppInfo> appI🔵
4132         Runnable r = new Runnable() {                                                                    
4133             public void run() {                                                                          
4134                 bindComponentsRemoved(packageNames, appInfos, user, reason);                             
4135             }                                                                                            
4136         };                                                                                               
4137         if (waitUntilResume(r)) {                                                                        
4138             return;                                                                                      
4139         }                                                                                                
4140         if (reason == 0) {                                                                               
4141             HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                     
4142             for (AppInfo info : appInfos) {                                                              
4143                 removedComponents.add(info.componentName);                                               
4144             }                                                                                            
4145             if (!packageNames.isEmpty()) {                                                               
4146                 mWorkspace.removeItemsByPackageName(packageNames, user);                                 
4147             }                                                                                            
4148             if (!removedComponents.isEmpty()) {                                                          
4149                 mWorkspace.removeItemsByComponentName(removedComponents, user);                          
4150             }                                                                                            
4151             // Notify the drag controller                                                                
4152             mDragController.onAppsRemoved(packageNames, removedComponents);                              
4153         } else {                                                                                         
4154             mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                        
4155         }                                                                                                
4156         // Update AllApps                                                                                
4157         if (mAppsView != null) {                                                                         
4158             mAppsView.removeApps(appInfos);                                                              
4159         }                                                                                                
4160     }                                                                                                    
4161                                                                                                          
4162     /**                                                                                                  
4163      * A number of packages were updated.                                                                
4164      */                                                                                                  
4165     @Thunk                                                                                               
4166     ArrayList<Object> mWidgetsAndShortcuts;                                                              
4167                                                                                                          
4168     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                     
4169             public void run() {                                                                          
4170                 bindPackagesUpdated(mWidgetsAndShortcuts);                                               
4171                 mWidgetsAndShortcuts = null;                                                             
4172             }                                                                                            
4173         };                                                                                               
4174                                                                                                          
4175     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                       
4176         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                       
4177             mWidgetsAndShortcuts = widgetsAndShortcuts;                                                  
4178             return;                                                                                      
4179         }                                                                                                
4180         if (mWidgetsView != null) {                                                                      
4181             mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false), getPackageMa🔵
4182         }                                                                                                
4183     }                                                                                                    
4184                                                                                                          
4185     private int mapConfigurationOriActivityInfoOri(int configOri) {                                      
4186         final Display d = getWindowManager().getDefaultDisplay();                                        
4187         int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                            
4188         switch (d.getRotation()) {                                                                       
4189         case Surface.ROTATION_0:                                                                         
4190         case Surface.ROTATION_180:                                                                       
4191             // We are currently in the same basic orientation as the natural orientation                 
4192             naturalOri = configOri;                                                                      
4193             break;                                                                                       
4194         case Surface.ROTATION_90:                                                                        
4195         case Surface.ROTATION_270:                                                                       
4196             // We are currently in the other basic orientation to the natural orientation                
4197             naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                            
4198                     Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;            
4199             break;                                                                                       
4200         }                                                                                                
4201                                                                                                          
4202         int[] oriMap = {                                                                                 
4203                 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                
4204                 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                               
4205                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                        
4206                 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                        
4207         };                                                                                               
4208         // Since the map starts at portrait, we need to offset if this device's natural orientation      
4209         // is landscape.                                                                                 
4210         int indexOffset = 0;                                                                             
4211         if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                         
4212             indexOffset = 1;                                                                             
4213         }                                                                                                
4214         return oriMap[(d.getRotation() + indexOffset) % 4];                                              
4215     }                                                                                                    
4216                                                                                                          
4217     public void lockScreenOrientation() {                                                                
4218         if (Utilities.isRotationEnabled(this)) {                                                         
4219             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                            
4220                 setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                
4221                         .getConfiguration().orientation));                                               
4222             } else {                                                                                     
4223                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                         
4224             }                                                                                            
4225         }                                                                                                
4226     }                                                                                                    
4227                                                                                                          
4228     public void unlockScreenOrientation(boolean immediate) {                                             
4229         if (Utilities.isRotationEnabled(this)) {                                                         
4230             if (immediate) {                                                                             
4231                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                    
4232             } else {                                                                                     
4233                 mHandler.postDelayed(new Runnable() {                                                    
4234                     public void run() {                                                                  
4235                         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);            
4236                     }                                                                                    
4237                 }, mRestoreScreenOrientationDelay);                                                      
4238             }                                                                                            
4239         }                                                                                                
4240     }                                                                                                    
4241                                                                                                          
4242     protected boolean isLauncherPreinstalled() {                                                         
4243         if (mLauncherCallbacks != null) {                                                                
4244             return mLauncherCallbacks.isLauncherPreinstalled();                                          
4245         }                                                                                                
4246         PackageManager pm = getPackageManager();                                                         
4247         try {                                                                                            
4248             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);          
4249             if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                         
4250                 return true;                                                                             
4251             } else {                                                                                     
4252                 return false;                                                                            
4253             }                                                                                            
4254         } catch (NameNotFoundException e) {                                                              
4255             e.printStackTrace();                                                                         
4256             return false;                                                                                
4257         }                                                                                                
4258     }                                                                                                    
4259                                                                                                          
4260     /**                                                                                                  
4261      * This method indicates whether or not we should suggest default wallpaper dimensions               
4262      * when our wallpaper cropper was not yet used to set a wallpaper.                                   
4263      */                                                                                                  
4264     protected boolean overrideWallpaperDimensions() {                                                    
4265         if (mLauncherCallbacks != null) {                                                                
4266             return mLauncherCallbacks.overrideWallpaperDimensions();                                     
4267         }                                                                                                
4268         return true;                                                                                     
4269     }                                                                                                    
4270                                                                                                          
4271     /**                                                                                                  
4272      * To be overridden by subclasses to indicate that there is an activity to launch                    
4273      * before showing the standard launcher experience.                                                  
4274      */                                                                                                  
4275     protected boolean hasFirstRunActivity() {                                                            
4276         if (mLauncherCallbacks != null) {                                                                
4277             return mLauncherCallbacks.hasFirstRunActivity();                                             
4278         }                                                                                                
4279         return false;                                                                                    
4280     }                                                                                                    
4281                                                                                                          
4282     /**                                                                                                  
4283      * To be overridden by subclasses to launch any first run activity                                   
4284      */                                                                                                  
4285     protected Intent getFirstRunActivity() {                                                             
4286         if (mLauncherCallbacks != null) {                                                                
4287             return mLauncherCallbacks.getFirstRunActivity();                                             
4288         }                                                                                                
4289         return null;                                                                                     
4290     }                                                                                                    
4291                                                                                                          
4292     /**                                                                                                  
4293      * Returns whether the launcher callbacks overrides search in all apps.                              
4294      * @return                                                                                           
4295      */                                                                                                  
4296     @Thunk                                                                                               
4297     boolean isAllAppsSearchOverridden() {                                                                
4298         if (mLauncherCallbacks != null) {                                                                
4299             return mLauncherCallbacks.overrideAllAppsSearch();                                           
4300         }                                                                                                
4301         return false;                                                                                    
4302     }                                                                                                    
4303                                                                                                          
4304     private boolean shouldRunFirstRunActivity() {                                                        
4305         return !ActivityManager.isRunningInTestHarness() &&                                              
4306                 !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                           
4307     }                                                                                                    
4308                                                                                                          
4309     protected boolean hasRunFirstRunActivity() {                                                         
4310         return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                             
4311     }                                                                                                    
4312                                                                                                          
4313     public boolean showFirstRunActivity() {                                                              
4314         if (shouldRunFirstRunActivity() &&                                                               
4315                 hasFirstRunActivity()) {                                                                 
4316             Intent firstRunIntent = getFirstRunActivity();                                               
4317             if (firstRunIntent != null) {                                                                
4318                 startActivity(firstRunIntent);                                                           
4319                 markFirstRunActivityShown();                                                             
4320                 return true;                                                                             
4321             }                                                                                            
4322         }                                                                                                
4323         return false;                                                                                    
4324     }                                                                                                    
4325                                                                                                          
4326     private void markFirstRunActivityShown() {                                                           
4327         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4328         editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                           
4329         editor.apply();                                                                                  
4330     }                                                                                                    
4331                                                                                                          
4332     /**                                                                                                  
4333      * To be overridden by subclasses to indicate that there is an in-activity full-screen intro         
4334      * screen that must be displayed and dismissed.                                                      
4335      */                                                                                                  
4336     protected boolean hasDismissableIntroScreen() {                                                      
4337         if (mLauncherCallbacks != null) {                                                                
4338             return mLauncherCallbacks.hasDismissableIntroScreen();                                       
4339         }                                                                                                
4340         return false;                                                                                    
4341     }                                                                                                    
4342                                                                                                          
4343     /**                                                                                                  
4344      * Full screen intro screen to be shown and dismissed before the launcher can be used.               
4345      */                                                                                                  
4346     protected View getIntroScreen() {                                                                    
4347         if (mLauncherCallbacks != null) {                                                                
4348             return mLauncherCallbacks.getIntroScreen();                                                  
4349         }                                                                                                
4350         return null;                                                                                     
4351     }                                                                                                    
4352                                                                                                          
4353     /**                                                                                                  
4354      * To be overriden by subclasses to indicate whether the in-activity intro screen has been           
4355      * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                    
4356      */                                                                                                  
4357     private boolean shouldShowIntroScreen() {                                                            
4358         return hasDismissableIntroScreen() &&                                                            
4359                 !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                 
4360     }                                                                                                    
4361                                                                                                          
4362     protected void showIntroScreen() {                                                                   
4363         View introScreen = getIntroScreen();                                                             
4364         changeWallpaperVisiblity(false);                                                                 
4365         if (introScreen != null) {                                                                       
4366             mDragLayer.showOverlayView(introScreen);                                                     
4367         }                                                                                                
4368         if (mLauncherOverlayContainer != null) {                                                         
4369             mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                     
4370         }                                                                                                
4371     }                                                                                                    
4372                                                                                                          
4373     public void dismissIntroScreen() {                                                                   
4374         markIntroScreenDismissed();                                                                      
4375         if (showFirstRunActivity()) {                                                                    
4376             // We delay hiding the intro view until the first run activity is showing. This              
4377             // avoids a blip.                                                                            
4378             mWorkspace.postDelayed(new Runnable() {                                                      
4379                 @Override                                                                                
4380                 public void run() {                                                                      
4381                     mDragLayer.dismissOverlayView();                                                     
4382                     if (mLauncherOverlayContainer != null) {                                             
4383                         mLauncherOverlayContainer.setVisibility(View.VISIBLE);                           
4384                     }                                                                                    
4385                     showFirstRunClings();                                                                
4386                 }                                                                                        
4387             }, ACTIVITY_START_DELAY);                                                                    
4388         } else {                                                                                         
4389             mDragLayer.dismissOverlayView();                                                             
4390             if (mLauncherOverlayContainer != null) {                                                     
4391                 mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                   
4392             }                                                                                            
4393             showFirstRunClings();                                                                        
4394         }                                                                                                
4395         changeWallpaperVisiblity(true);                                                                  
4396     }                                                                                                    
4397                                                                                                          
4398     private void markIntroScreenDismissed() {                                                            
4399         SharedPreferences.Editor editor = mSharedPrefs.edit();                                           
4400         editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                 
4401         editor.apply();                                                                                  
4402     }                                                                                                    
4403                                                                                                          
4404     @Thunk                                                                                               
4405     void showFirstRunClings() {                                                                          
4406         // The two first run cling paths are mutually exclusive, if the launcher is preinstalled         
4407         // on the device, then we always show the first run cling experience (or if there is no          
4408         // launcher2). Otherwise, we prompt the user upon started for migration                          
4409         LauncherClings launcherClings = new LauncherClings(this);                                        
4410         if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                      
4411             if (mModel.canMigrateFromOldLauncherDb(this)) {                                              
4412                 launcherClings.showMigrationCling();                                                     
4413             } else {                                                                                     
4414                 launcherClings.showLongPressCling(true);                                                 
4415             }                                                                                            
4416         }                                                                                                
4417     }                                                                                                    
4418                                                                                                          
4419     void showWorkspaceSearchAndHotseat() {                                                               
4420         if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                 
4421         if (mHotseat != null) mHotseat.setAlpha(1f);                                                     
4422         if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                       
4423         if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                     
4424     }                                                                                                    
4425                                                                                                          
4426     void hideWorkspaceSearchAndHotseat() {                                                               
4427         if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                 
4428         if (mHotseat != null) mHotseat.setAlpha(0f);                                                     
4429         if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                       
4430         if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                     
4431     }                                                                                                    
4432                                                                                                          
4433     public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                          
4434         // Called from search suggestion, not supported in other profiles.                               
4435         final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                 
4436         LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                          
4437         LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent, myUser); 
4438         if (activityInfo == null) {                                                                      
4439             return null;                                                                                 
4440         }                                                                                                
4441         return new AppInfo(this, activityInfo, myUser, mIconCache);                                      
4442     }                                                                                                    
4443                                                                                                          
4444     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4445             Bitmap icon) {                                                                               
4446         // Called from search suggestion, not supported in other profiles.                               
4447         return createShortcutDragInfo(shortcutIntent, caption, icon,                                     
4448                 UserHandleCompat.myUserHandle());                                                        
4449     }                                                                                                    
4450                                                                                                          
4451     public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                  
4452             Bitmap icon, UserHandleCompat user) {                                                        
4453         UserManagerCompat userManager = UserManagerCompat.getInstance(this);                             
4454         CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);              
4455         return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                
4456     }                                                                                                    
4457                                                                                                          
4458     protected void moveWorkspaceToDefaultScreen() {                                                      
4459         mWorkspace.moveToDefaultScreen(false);                                                           
4460     }                                                                                                    
4461                                                                                                          
4462     public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                         
4463         dragView.setTag(dragInfo);                                                                       
4464         mWorkspace.onExternalDragStartedWithItem(dragView);                                              
4465         mWorkspace.beginExternalDragShared(dragView, source);                                            
4466     }                                                                                                    
4467                                                                                                          
4468     @Override                                                                                            
4469     public void onPageSwitch(View newPage, int newPageIndex) {                                           
4470         if (mLauncherCallbacks != null) {                                                                
4471             mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                      
4472         }                                                                                                
4473     }                                                                                                    
4474                                                                                                          
4475     /**                                                                                                  
4476      * Prints out out state for debugging.                                                               
4477      */                                                                                                  
4478     public void dumpState() {                                                                            
4479         Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                   
4480         Log.d(TAG, "mSavedState=" + mSavedState);                                                        
4481         Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                            
4482         Log.d(TAG, "mRestoring=" + mRestoring);                                                          
4483         Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                            
4484         Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                        
4485         Log.d(TAG, "sFolders.size=" + sFolders.size());                                                  
4486         mModel.dumpState();                                                                              
4487         // TODO(hyunyoungs): add mWidgetsView.dumpState(); or mWidgetsModel.dumpState();                 
4488         Log.d(TAG, "END launcher3 dump state");                                                          
4489     }                                                                                                    
4490                                                                                                          
4491     @Override                                                                                            
4492     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {              
4493         super.dump(prefix, fd, writer, args);                                                            
4494         synchronized (sDumpLogs) {                                                                       
4495             writer.println(" ");                                                                         
4496             writer.println("Debug logs: ");                                                              
4497             for (int i = 0; i < sDumpLogs.size(); i++) {                                                 
4498                 writer.println("  " + sDumpLogs.get(i));                                                 
4499             }                                                                                            
4500         }                                                                                                
4501         if (mLauncherCallbacks != null) {                                                                
4502             mLauncherCallbacks.dump(prefix, fd, writer, args);                                           
4503         }                                                                                                
4504     }                                                                                                    
4505                                                                                                          
4506     public static void dumpDebugLogsToConsole() {                                                        
4507         if (DEBUG_DUMP_LOG) {                                                                            
4508             synchronized (sDumpLogs) {                                                                   
4509                 Log.d(TAG, "");                                                                          
4510                 Log.d(TAG, "*********************");                                                     
4511                 Log.d(TAG, "Launcher debug logs: ");                                                     
4512                 for (int i = 0; i < sDumpLogs.size(); i++) {                                             
4513                     Log.d(TAG, "  " + sDumpLogs.get(i));                                                 
4514                 }                                                                                        
4515                 Log.d(TAG, "*********************");                                                     
4516                 Log.d(TAG, "");                                                                          
4517             }                                                                                            
4518         }                                                                                                
4519     }                                                                                                    
4520                                                                                                          
4521     public static void addDumpLog(String tag, String log, boolean debugLog) {                            
4522         addDumpLog(tag, log, null, debugLog);                                                            
4523     }                                                                                                    
4524                                                                                                          
4525     public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {               
4526         if (debugLog) {                                                                                  
4527             if (e != null) {                                                                             
4528                 Log.d(tag, log, e);                                                                      
4529             } else {                                                                                     
4530                 Log.d(tag, log);                                                                         
4531             }                                                                                            
4532         }                                                                                                
4533         if (DEBUG_DUMP_LOG) {                                                                            
4534             sDateStamp.setTime(System.currentTimeMillis());                                              
4535             synchronized (sDumpLogs) {                                                                   
4536                 sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                   
4537                     + (e == null ? "" : (", Exception: " + e)));                                         
4538             }                                                                                            
4539         }                                                                                                
4540     }                                                                                                    
4541                                                                                                          
4542     public static CustomAppWidget getCustomAppWidget(String name) {                                      
4543         return sCustomAppWidgets.get(name);                                                              
4544     }                                                                                                    
4545                                                                                                          
4546     public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                               
4547         return sCustomAppWidgets;                                                                        
4548     }                                                                                                    
4549                                                                                                          
4550     public void dumpLogsToLocalData() {                                                                  
4551         if (DEBUG_DUMP_LOG) {                                                                            
4552             new AsyncTask<Void, Void, Void>() {                                                          
4553                 public Void doInBackground(Void ... args) {                                              
4554                     boolean success = false;                                                             
4555                     sDateStamp.setTime(sRunStart);                                                       
4556                     String FILENAME = sDateStamp.getMonth() + "-"                                        
4557                             + sDateStamp.getDay() + "_"                                                  
4558                             + sDateStamp.getHours() + "-"                                                
4559                             + sDateStamp.getMinutes() + "_"                                              
4560                             + sDateStamp.getSeconds() + ".txt";                                          
4561                                                                                                          
4562                     FileOutputStream fos = null;                                                         
4563                     File outFile = null;                                                                 
4564                     try {                                                                                
4565                         outFile = new File(getFilesDir(), FILENAME);                                     
4566                         outFile.createNewFile();                                                         
4567                         fos = new FileOutputStream(outFile);                                             
4568                     } catch (Exception e) {                                                              
4569                         e.printStackTrace();                                                             
4570                     }                                                                                    
4571                     if (fos != null) {                                                                   
4572                         PrintWriter writer = new PrintWriter(fos);                                       
4573                                                                                                          
4574                         writer.println(" ");                                                             
4575                         writer.println("Debug logs: ");                                                  
4576                         synchronized (sDumpLogs) {                                                       
4577                             for (int i = 0; i < sDumpLogs.size(); i++) {                                 
4578                                 writer.println("  " + sDumpLogs.get(i));                                 
4579                             }                                                                            
4580                         }                                                                                
4581                         writer.close();                                                                  
4582                     }                                                                                    
4583                     try {                                                                                
4584                         if (fos != null) {                                                               
4585                             fos.close();                                                                 
4586                             success = true;                                                              
4587                         }                                                                                
4588                     } catch (IOException e) {                                                            
4589                         e.printStackTrace();                                                             
4590                     }                                                                                    
4591                     return null;                                                                         
4592                 }                                                                                        
4593             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                            
4594         }                                                                                                
4595     }                                                                                                    
4596 }                                                                                                        
4597                                                                                                          
4598 interface LauncherTransitionable {                                                                       
4599     public abstract View getContent();                                                                   
4600                                                                                                          
4601     public abstract void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace); 
4602                                                                                                          
4603     public abstract void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);   
4604                                                                                                          
4605     public abstract void onLauncherTransitionStep(Launcher l, float t);                                  
4606                                                                                                          
4607     public abstract void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);     
4608 }                                                                                                        








































































































































































ours vs. base theirs vs. base
   1 -                                                                                                                  
   2  /*                                                                                                                
   3   * Copyright (C) 2008 The Android Open Source Project                                                             
   4   *                                                                                                                
   5   * Licensed under the Apache License, Version 2.0 (the "License");                                                
   6   * you may not use this file except in compliance with the License.                                               
   7   * You may obtain a copy of the License at                                                                        
   8   *                                                                                                                
   9   *      http://www.apache.org/licenses/LICENSE-2.0                                                                
  10   *                                                                                                                
  11   * Unless required by applicable law or agreed to in writing, software                                            
  12   * distributed under the License is distributed on an "AS IS" BASIS,                                              
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                       
  14   * See the License for the specific language governing permissions and                                            
  15   * limitations under the License.                                                                                 
  16   */                                                                                                               
  17                                                                                                                    
  18  package com.android.launcher3;                                                                                    
  19                                                                                                                    
  20  import android.animation.Animator;                                                                                
  21  import android.animation.AnimatorListenerAdapter;                                                                 
  22  import android.animation.AnimatorSet;                                                                             
  23  import android.animation.ObjectAnimator;                                                                          
  24  import android.animation.PropertyValuesHolder;                                                                    
  25 -import android.animation.TimeInterpolator;                                                                        
  26  import android.animation.ValueAnimator;                                                                           
  27  import android.annotation.TargetApi;                                                                              
  28  import android.app.Activity;                                                                                      
  29  import android.app.ActivityManager;                                                                               
  30  import android.app.ActivityOptions;                                                                               
  31  import android.app.AlertDialog;                                                                                   
  32  import android.app.SearchManager;                                                                                 
  33  import android.appwidget.AppWidgetHostView;                                                                       
  34  import android.appwidget.AppWidgetManager;                                                                        
  35  import android.appwidget.AppWidgetProviderInfo;                                                                   
  36  import android.content.ActivityNotFoundException;                                                                 
  37  import android.content.BroadcastReceiver;                                                                         
  38  import android.content.ComponentCallbacks2;                                                                       
  39  import android.content.ComponentName;                                                                             
  40  import android.content.ContentResolver;                                                                           
  41  import android.content.Context;                                                                                   
  42  import android.content.DialogInterface;                                                                           
  43  import android.content.Intent;                                                                                    
  44  import android.content.IntentFilter;                                                                              
  45  import android.content.IntentSender;                                                                              
  46  import android.content.SharedPreferences;                                                                         
  47  import android.content.pm.ActivityInfo;                                                                           
  48  import android.content.pm.ApplicationInfo;                                                                        
  49  import android.content.pm.PackageManager;                                                                         
  50  import android.content.pm.PackageManager.NameNotFoundException;                                                   
  51  import android.content.res.Configuration;                                                                         
  52 -import android.content.res.Resources;                                                                             
  53  import android.database.ContentObserver;                                                                          
  54  import android.database.sqlite.SQLiteDatabase;                                                                    
  55  import android.graphics.Bitmap;                                                                                   
  56  import android.graphics.Canvas;                                                                                   
  57  import android.graphics.Color;                                                                                    
  58  import android.graphics.PorterDuff;                                                                               
  59  import android.graphics.Rect;                                                                                     
  60  import android.graphics.drawable.Drawable;                                                                        
  61  import android.net.Uri;                                                                                           
  62  import android.os.AsyncTask;                                                                                      
  63  import android.os.Build;                                                                                          
  64  import android.os.Bundle;                                                                                         
  65  import android.os.Environment;                                                                                    
  66  import android.os.Handler;                                                                                        
  67  import android.os.Message;                                                                                        
  68  import android.os.StrictMode;                                                                                     
  69  import android.os.SystemClock;                                                                                    
  70  import android.text.Selection;                                                                                    
  71  import android.text.SpannableStringBuilder;                                                                       
  72  import android.text.TextUtils;                                                                                    
  73  import android.text.method.TextKeyListener;                                                                       
  74  import android.util.Log;                                                                                          
  75  import android.view.Display;                                                                                      
  76  import android.view.Gravity;                                                                                      
  77  import android.view.HapticFeedbackConstants;                                                                      
  78  import android.view.KeyEvent;                                                                                     
  79  import android.view.LayoutInflater;                                                                               
  80  import android.view.Menu;                                                                                         
  81  import android.view.MotionEvent;                                                                                  
  82  import android.view.Surface;                                                                                      
  83  import android.view.View;                                                                                         
  84  import android.view.View.OnClickListener;                                                                         
  85  import android.view.View.OnLongClickListener;                                                                     
  86 -import android.view.ViewAnimationUtils;                                                                           
  87  import android.view.ViewGroup;                                                                                    
  88  import android.view.ViewStub;                                                                                     
  89  import android.view.ViewTreeObserver;                                                                             
  90  import android.view.Window;                                                                                       
  91  import android.view.WindowManager;                                                                                
  92  import android.view.accessibility.AccessibilityEvent;                                                             
  93 -import android.view.animation.AccelerateInterpolator;                                                             
  94 -import android.view.animation.DecelerateInterpolator;                                                             
  95  import android.view.inputmethod.InputMethodManager;                                                               
  96  import android.widget.Advanceable;                                                                                
  97  import android.widget.FrameLayout;                                                                                
  98  import android.widget.ImageView;                                                                                  
  99 +import android.widget.TextView;                                                                                   
 100  import android.widget.Toast;                                                                                      
 101                                                                                                                    
 102  import com.android.launcher3.DropTarget.DragObject;                                                               
 103  import com.android.launcher3.PagedView.PageSwitchListener;                                                        
 104  import com.android.launcher3.compat.AppWidgetManagerCompat;                                                       
 105  import com.android.launcher3.compat.LauncherActivityInfoCompat;                                                   
 106  import com.android.launcher3.compat.LauncherAppsCompat;                                                           
 107  import com.android.launcher3.compat.PackageInstallerCompat;                                                       
 108  import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                                    
 109  import com.android.launcher3.compat.UserHandleCompat;                                                             
 110  import com.android.launcher3.compat.UserManagerCompat;                                                            
 111 +import com.android.launcher3.util.Thunk;                                                                          
 112 +import com.android.launcher3.widget.PendingAddWidgetInfo;                                                         
 113 +import com.android.launcher3.widget.WidgetsContainerView;                                                         
 114                                                                                                                    
 115  import java.io.DataInputStream;                                                                                   
 116  import java.io.DataOutputStream;                                                                                  
 117  import java.io.File;                                                                                              
 118  import java.io.FileDescriptor;                                                                                    
 119  import java.io.FileNotFoundException;                                                                             
 120  import java.io.FileOutputStream;                                                                                  
 121  import java.io.IOException;                                                                                       
 122  import java.io.PrintWriter;                                                                                       
 123 -import java.lang.reflect.Field;                                                                                   
 124  import java.lang.reflect.InvocationTargetException;                                                               
 125  import java.lang.reflect.Method;                                                                                  
 126  import java.text.DateFormat;                                                                                      
 127  import java.util.ArrayList;                                                                                       
 128  import java.util.Collection;                                                                                      
 129  import java.util.Date;                                                                                            
 130  import java.util.HashMap;                                                                                         
 131  import java.util.HashSet;                                                                                         
 132  import java.util.List;                                                                                            
 133  import java.util.concurrent.atomic.AtomicInteger;                                                                 
 134                                                                                                                    
 135  /**                                                                                                               
 136   * Default launcher application.                                                                                  
 137   */                                                                                                               
 138  public class Launcher extends Activity                                                                            
 139          implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                            
 140 -                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {                     
 141 +                   View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,                      
 142 +                   LauncherStateTransitionAnimation.Callbacks {                                                   
 143      static final String TAG = "Launcher";                                                                         
 144 -    static final boolean LOGD = false;                                                                            
 145 +    static final boolean LOGD = true;                                                                             
 146                                                                                                                    
 147      static final boolean PROFILE_STARTUP = false;                                                                 
 148 -    static final boolean DEBUG_WIDGETS = false;                                                                   
 149 +    static final boolean DEBUG_WIDGETS = true;                                                                    
 150      static final boolean DEBUG_STRICT_MODE = false;                                                               
 151      static final boolean DEBUG_RESUME_TIME = false;                                                               
 152      static final boolean DEBUG_DUMP_LOG = false;                                                                  
 153                                                                                                                    
 154      static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                               
 155                                                                                                                    
 156      private static final int REQUEST_CREATE_SHORTCUT = 1;                                                         
 157      private static final int REQUEST_CREATE_APPWIDGET = 5;                                                        
 158 -    private static final int REQUEST_PICK_SHORTCUT = 7;                                                           
 159      private static final int REQUEST_PICK_APPWIDGET = 9;                                                          
 160      private static final int REQUEST_PICK_WALLPAPER = 10;                                                         
 161                                                                                                                    
 162      private static final int REQUEST_BIND_APPWIDGET = 11;                                                         
 163      private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                                  
 164                                                                                                                    
 165      /**                                                                                                           
 166       * IntentStarter uses request codes starting with this. This must be greater than all activity                
 167       * request codes used internally.                                                                             
 168       */                                                                                                           
 169      protected static final int REQUEST_LAST = 100;                                                                
 170                                                                                                                    
 171      static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                                   
 172                                                                                                                    
 173      static final int SCREEN_COUNT = 5;                                                                            
 174                                                                                                                    
 175      // To turn on these properties, type                                                                          
 176      // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                               
 177      static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                              
 178 -    static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                         
 179                                                                                                                    
 180      // The Intent extra that defines whether to ignore the launch animation                                       
 181      static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                                    
 182              "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                                
 183                                                                                                                    
 184      // Type: int                                                                                                  
 185      private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                         
 186      // Type: int                                                                                                  
 187      private static final String RUNTIME_STATE = "launcher.state";                                                 
 188      // Type: int                                                                                                  
 189      private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";                   
 190      // Type: int                                                                                                  
 191      private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                         
 192      // Type: int                                                                                                  
 193      private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                         
 194      // Type: int                                                                                                  
 195      private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                         
 196      // Type: boolean                                                                                              
 197      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";                   
 198      // Type: long                                                                                                 
 199      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";             
 200      // Type: int                                                                                                  
 201      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                         
 202      // Type: int                                                                                                  
 203      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                         
 204      // Type: parcelable                                                                                           
 205      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";               
 206      // Type: parcelable                                                                                           
 207      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";                   
 208      // Type: int[]                                                                                                
 209      private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                                     
 210                                                                                                                    
 211      static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                               
 212      static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";                   
 213                                                                                                                    
 214      static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                                     
 215      static final String ACTION_FIRST_LOAD_COMPLETE =                                                              
 216              "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                                   
 217                                                                                                                    
 218      public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                            
 219      public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                              
 220                                                                                                                    
 221      private static final String QSB_WIDGET_ID = "qsb_widget_id";                                                  
 222      private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                                      
 223                                                                                                                    
 224      public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";                        
 225                                                                                                                    
 226      /** The different states that Launcher can be in. */                                                          
 227 -    private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                         
 228 -    private State mState = State.WORKSPACE;                                                                       
 229 -    private AnimatorSet mStateAnimation;                                                                          
 230 +    enum State { NONE, WORKSPACE, APPS, APPS_SPRING_LOADED, WIDGETS, WIDGETS_SPRING_LOADED };                     
 231 +    @Thunk State mState = State.WORKSPACE;                                                                        
 232 +    @Thunk AnimatorSet mStateAnimation;                                                                           
 233 +    @Thunk LauncherStateTransitionAnimation mStateTransitionAnimation;                                            
 234                                                                                                                    
 235      private boolean mIsSafeModeEnabled;                                                                           
 236                                                                                                                    
 237      LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();                      
 238      LauncherOverlay mLauncherOverlay;                                                                             
 239      InsettableFrameLayout mLauncherOverlayContainer;                                                              
 240                                                                                                                    
 241      static final int APPWIDGET_HOST_ID = 1024;                                                                    
 242      public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                           
 243      private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                            
 244      private static final int ACTIVITY_START_DELAY = 1000;                                                         
 245                                                                                                                    
 246 -    private static final Object sLock = new Object();                                                             
 247 -                                                                                                                  
 248      private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                          
 249      private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                                   
 250                                                                                                                    
 251      // How long to wait before the new-shortcut animation automatically pans the workspace                        
 252      private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                            
 253      private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                           
 254 -    private static int NEW_APPS_ANIMATION_DELAY = 500;                                                            
 255 -    private static final int SINGLE_FRAME_DELAY = 16;                                                             
 256 +    @Thunk static int NEW_APPS_ANIMATION_DELAY = 500;                                                             
 257                                                                                                                    
 258      private final BroadcastReceiver mCloseSystemDialogsReceiver                                                   
 259              = new CloseSystemDialogsIntentReceiver();                                                             
 260      private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                                 
 261                                                                                                                    
 262      private LayoutInflater mInflater;                                                                             
 263                                                                                                                    
 264 -    private Workspace mWorkspace;                                                                                 
 265 +    @Thunk Workspace mWorkspace;                                                                                  
 266      private View mLauncherView;                                                                                   
 267      private View mPageIndicators;                                                                                 
 268 -    private DragLayer mDragLayer;                                                                                 
 269 +    @Thunk DragLayer mDragLayer;                                                                                  
 270      private DragController mDragController;                                                                       
 271      private View mWeightWatcher;                                                                                  
 272                                                                                                                    
 273      private AppWidgetManagerCompat mAppWidgetManager;                                                             
 274      private LauncherAppWidgetHost mAppWidgetHost;                                                                 
 275                                                                                                                    
 276 -    private ItemInfo mPendingAddInfo = new ItemInfo();                                                            
 277 +    @Thunk ItemInfo mPendingAddInfo = new ItemInfo();                                                             
 278      private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                                  
 279      private int mPendingAddWidgetId = -1;                                                                         
 280                                                                                                                    
 281      private int[] mTmpAddItemCellCoordinates = new int[2];                                                        
 282                                                                                                                    
 283      private FolderInfo mFolderInfo;                                                                               
 284                                                                                                                    
 285      private Hotseat mHotseat;                                                                                     
 286      private ViewGroup mOverviewPanel;                                                                             
 287                                                                                                                    
 288      private View mAllAppsButton;                                                                                  
 289                                                                                                                    
 290      private SearchDropTargetBar mSearchDropTargetBar;                                                             
 291 -    private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                           
 292 -    private AppsCustomizePagedView mAppsCustomizeContent;                                                         
 293 +                                                                                                                  
 294 +    // Main container view for the all apps screen.                                                               
 295 +    @Thunk AppsContainerView mAppsView;                                                                           
 296 +                                                                                                                  
 297 +    // Main container view for the widget tray screen.                                                            
 298 +    private WidgetsContainerView mWidgetsView;                                                                    
 299 +                                                                                                                  
 300      private boolean mAutoAdvanceRunning = false;                                                                  
 301      private AppWidgetHostView mQsb;                                                                               
 302                                                                                                                    
 303      private Bundle mSavedState;                                                                                   
 304      // We set the state in both onCreate and then onNewIntent in some cases, which causes both                    
 305      // scroll issues (because the workspace may not have been measured yet) and extra work.                       
 306      // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.               
 307      private State mOnResumeState = State.NONE;                                                                    
 308                                                                                                                    
 309      private SpannableStringBuilder mDefaultKeySsb = null;                                                         
 310                                                                                                                    
 311 -    private boolean mWorkspaceLoading = true;                                                                     
 312 +    @Thunk boolean mWorkspaceLoading = true;                                                                      
 313                                                                                                                    
 314      private boolean mPaused = true;                                                                               
 315      private boolean mRestoring;                                                                                   
 316      private boolean mWaitingForResult;                                                                            
 317      private boolean mOnResumeNeedsLoad;                                                                           
 318                                                                                                                    
 319      private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                               
 320      private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                                   
 321                                                                                                                    
 322      private Bundle mSavedInstanceState;                                                                           
 323                                                                                                                    
 324      private LauncherModel mModel;                                                                                 
 325      private IconCache mIconCache;                                                                                 
 326 -    private boolean mUserPresent = true;                                                                          
 327 +    @Thunk boolean mUserPresent = true;                                                                           
 328      private boolean mVisible = false;                                                                             
 329      private boolean mHasFocus = false;                                                                            
 330      private boolean mAttached = false;                                                                            
 331                                                                                                                    
 332 -    private static LocaleConfiguration sLocaleConfiguration = null;                                               
 333 +    @Thunk static LocaleConfiguration sLocaleConfiguration = null;                                                
 334                                                                                                                    
 335      private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                          
 336                                                                                                                    
 337      private View.OnTouchListener mHapticFeedbackTouchListener;                                                    
 338 -                                                                                                                  
 339 -    public static final int BUILD_LAYER = 0;                                                                      
 340 -    public static final int BUILD_AND_SET_LAYER = 1;                                                              
 341                                                                                                                    
 342      // Related to the auto-advancing of widgets                                                                   
 343      private final int ADVANCE_MSG = 1;                                                                            
 344      private final int mAdvanceInterval = 20000;                                                                   
 345      private final int mAdvanceStagger = 250;                                                                      
 346      private long mAutoAdvanceSentTime;                                                                            
 347      private long mAutoAdvanceTimeLeft = -1;                                                                       
 348 -    private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                              
 349 +    @Thunk HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                               
 350          new HashMap<View, AppWidgetProviderInfo>();                                                               
 351                                                                                                                    
 352      // Determines how long to wait after a rotation before restoring the screen orientation to                    
 353      // match the sensor state.                                                                                    
 354      private final int mRestoreScreenOrientationDelay = 500;                                                       
 355                                                                                                                    
 356 -    private Drawable mWorkspaceBackgroundDrawable;                                                                
 357 +    @Thunk Drawable mWorkspaceBackgroundDrawable;                                                                 
 358                                                                                                                    
 359      private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                         
 360      private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                                
 361                                                                                                                    
 362      static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                           
 363      static Date sDateStamp = new Date();                                                                          
 364      static DateFormat sDateFormat =                                                                               
 365              DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                                   
 366      static long sRunStart = System.currentTimeMillis();                                                           
 367      static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                                        
 368                                                                                                                    
 369      // We only want to get the SharedPreferences once since it does an FS stat each time we get                   
 370      // it from the context.                                                                                       
 371      private SharedPreferences mSharedPrefs;                                                                       
 372                                                                                                                    
 373 -    private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                            
 374 -                                                                                                                  
 375      // Holds the page that we need to animate to, and the icon views that we need to animate up                   
 376      // when we scroll to that page on resume.                                                                     
 377 -    private ImageView mFolderIconImageView;                                                                       
 378 +    @Thunk ImageView mFolderIconImageView;                                                                        
 379      private Bitmap mFolderIconBitmap;                                                                             
 380      private Canvas mFolderIconCanvas;                                                                             
 381      private Rect mRectForFolderAnimation = new Rect();                                                            
 382                                                                                                                    
 383      private BubbleTextView mWaitingForResume;                                                                     
 384                                                                                                                    
 385      protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                         
 386              new HashMap<String, CustomAppWidget>();                                                               
 387                                                                                                                    
 388      private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                               
 389      static {                                                                                                      
 390          if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                          
 391              sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                                
 392          }                                                                                                         
 393      }                                                                                                             
 394                                                                                                                    
 395 -    private Runnable mBuildLayersRunnable = new Runnable() {                                                      
 396 +    // TODO: remove this field and call method directly when Launcher3 can depend on M APIs                       
 397 +    private static Method sClipRevealMethod = null;                                                               
 398 +    static {                                                                                                      
 399 +        Class<?> activityOptionsClass = ActivityOptions.class;                                                    
 400 +        try {                                                                                                     
 401 +            sClipRevealMethod = activityOptionsClass.getDeclaredMethod("makeClipRevealAnimation",                 
 402 +                    View.class, int.class, int.class, int.class, int.class);                                      
 403 +        } catch (Exception e) {                                                                                   
 404 +            // Earlier version                                                                                    
 405 +        }                                                                                                         
 406 +    }                                                                                                             
 407 +                                                                                                                  
 408 +    @Thunk Runnable mBuildLayersRunnable = new Runnable() {                                                       
 409          public void run() {                                                                                       
 410              if (mWorkspace != null) {                                                                             
 411                  mWorkspace.buildPageHardwareLayers();                                                             
 412              }                                                                                                     
 413          }                                                                                                         
 414      };                                                                                                            
 415                                                                                                                    
 416      private static PendingAddArguments sPendingAddItem;                                                           
 417                                                                                                                    
 418 -    private static class PendingAddArguments {                                                                    
 419 +    @Thunk static class PendingAddArguments {                                                                     
 420          int requestCode;                                                                                          
 421          Intent intent;                                                                                            
 422          long container;                                                                                           
 423          long screenId;                                                                                            
 424          int cellX;                                                                                                
 425          int cellY;                                                                                                
 426          int appWidgetId;                                                                                          
 427      }                                                                                                             
 428                                                                                                                    
 429      private Stats mStats;                                                                                         
 430                                                                                                                    
 431      FocusIndicatorView mFocusHandler;                                                                             
 432                                                                                                                    
 433      @Override                                                                                                     
 434      protected void onCreate(Bundle savedInstanceState) {                                                          
 435          if (DEBUG_STRICT_MODE) {                                                                                  
 436              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                                      
 437                      .detectDiskReads()                                                                            
 438                      .detectDiskWrites()                                                                           
 439                      .detectNetwork()   // or .detectAll() for all detectable problems                             
 440                      .penaltyLog()                                                                                 
 441                      .build());                                                                                    
 442              StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                              
 443                      .detectLeakedSqlLiteObjects()                                                                 
 444                      .detectLeakedClosableObjects()                                                                
 445                      .penaltyLog()                                                                                 
 446                      .penaltyDeath()                                                                               
 447                      .build());                                                                                    
 448          }                                                                                                         
 449                                                                                                                    
 450          if (mLauncherCallbacks != null) {                                                                         
 451              mLauncherCallbacks.preOnCreate();                                                                     
 452          }                                                                                                         
 453                                                                                                                    
 454          super.onCreate(savedInstanceState);                                                                       
 455                                                                                                                    
 456          LauncherAppState.setApplicationContext(getApplicationContext());                                          
 457          LauncherAppState app = LauncherAppState.getInstance();                                                    
 458          LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                           
 459                                                                                                                    
 460          // Lazy-initialize the dynamic grid                                                                       
 461          DeviceProfile grid = app.initDynamicGrid(this);                                                           
 462                                                                                                                    
 463          // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet   
 464          mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                           
 465                  Context.MODE_PRIVATE);                                                                            
 466          mIsSafeModeEnabled = getPackageManager().isSafeMode();                                                    
 467          mModel = app.setLauncher(this);                                                                           
 468          mIconCache = app.getIconCache();                                                                          
 469          mIconCache.flushInvalidIcons(grid);                                                                       
 470          mDragController = new DragController(this);                                                               
 471          mInflater = getLayoutInflater();                                                                          
 472 +        mStateTransitionAnimation = new LauncherStateTransitionAnimation(this, this);                             
 473                                                                                                                    
 474          mStats = new Stats(this);                                                                                 
 475                                                                                                                    
 476          mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                             
 477                                                                                                                    
 478          mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                                      
 479          mAppWidgetHost.startListening();                                                                          
 480                                                                                                                    
 481          // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,                
 482          // this also ensures that any synchronous binding below doesn't re-trigger another                        
 483          // LauncherModel load.                                                                                    
 484          mPaused = false;                                                                                          
 485                                                                                                                    
 486          if (PROFILE_STARTUP) {                                                                                    
 487              android.os.Debug.startMethodTracing(                                                                  
 488                      Environment.getExternalStorageDirectory() + "/launcher");                                     
 489          }                                                                                                         
 490                                                                                                                    
 491          checkForLocaleChange();                                                                                   
 492          setContentView(R.layout.launcher);                                                                        
 493                                                                                                                    
 494          setupViews();                                                                                             
 495          grid.layout(this);                                                                                        
 496                                                                                                                    
 497          registerContentObservers();                                                                               
 498                                                                                                                    
 499          lockAllApps();                                                                                            
 500                                                                                                                    
 501          mSavedState = savedInstanceState;                                                                         
 502          restoreState(mSavedState);                                                                                
 503                                                                                                                    
 504          if (PROFILE_STARTUP) {                                                                                    
 505              android.os.Debug.stopMethodTracing();                                                                 
 506          }                                                                                                         
 507                                                                                                                    
 508          if (!mRestoring) {                                                                                        
 509              if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                                       
 510                  // If the user leaves launcher, then we should just load items asynchronously when                
 511                  // they return.                                                                                   
 512                  mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                         
 513              } else {                                                                                              
 514                  // We only load the page synchronously if the user rotates (or triggers a                         
 515                  // configuration change) while launcher is in the foreground                                      
 516                  mModel.startLoader(true, mWorkspace.getRestorePage());                                            
 517              }                                                                                                     
 518          }                                                                                                         
 519                                                                                                                    
 520          // For handling default keys                                                                              
 521          mDefaultKeySsb = new SpannableStringBuilder();                                                            
 522          Selection.setSelection(mDefaultKeySsb, 0);                                                                
 523                                                                                                                    
 524          IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                               
 525          registerReceiver(mCloseSystemDialogsReceiver, filter);                                                    
 526                                                                                                                    
 527          // On large interfaces, we want the screen to auto-rotate based on the current orientation                
 528          unlockScreenOrientation(true);                                                                            
 529                                                                                                                    
 530          if (mLauncherCallbacks != null) {                                                                         
 531              mLauncherCallbacks.onCreate(savedInstanceState);                                                      
 532              if (mLauncherCallbacks.hasLauncherOverlay()) {                                                        
 533                  ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                              
 534                  mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                               
 535                  mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                                     
 536                          mLauncherOverlayContainer, mLauncherOverlayCallbacks);                                    
 537                  mWorkspace.setLauncherOverlay(mLauncherOverlay);                                                  
 538              }                                                                                                     
 539          }                                                                                                         
 540                                                                                                                    
 541          if (shouldShowIntroScreen()) {                                                                            
 542              showIntroScreen();                                                                                    
 543          } else {                                                                                                  
 544              showFirstRunActivity();                                                                               
 545              showFirstRunClings();                                                                                 
 546          }                                                                                                         
 547      }                                                                                                             
 548                                                                                                                    
 549      private LauncherCallbacks mLauncherCallbacks;                                                                 
 550                                                                                                                    
 551      public void onPostCreate(Bundle savedInstanceState) {                                                         
 552          super.onPostCreate(savedInstanceState);                                                                   
 553          if (mLauncherCallbacks != null) {                                                                         
 554              mLauncherCallbacks.onPostCreate(savedInstanceState);                                                  
 555          }                                                                                                         
 556      }                                                                                                             
 557                                                                                                                    
 558      public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                            
 559          mLauncherCallbacks = callbacks;                                                                           
 560 +        mLauncherCallbacks.setLauncherAppsCallback(new Launcher.LauncherAppsCallbacks() {                         
 561 +            @Override                                                                                             
 562 +            public void onAllAppsBoundsChanged(Rect bounds) {                                                     
 563 +                mAppsView.setFixedBounds(Launcher.this, bounds);                                                  
 564 +            }                                                                                                     
 565 +                                                                                                                  
 566 +            @Override                                                                                             
 567 +            public void dismissAllApps() {                                                                        
 568 +                showWorkspace(true);                                                                              
 569 +            }                                                                                                     
 570 +        });                                                                                                       
 571          return true;                                                                                              
 572      }                                                                                                             
 573                                                                                                                    
 574      @Override                                                                                                     
 575      public void onLauncherProviderChange() {                                                                      
 576          if (mLauncherCallbacks != null) {                                                                         
 577              mLauncherCallbacks.onLauncherProviderChange();                                                        
 578          }                                                                                                         
 579      }                                                                                                             
 580                                                                                                                    
 581      /** To be overridden by subclasses to hint to Launcher that we have custom content */                         
 582      protected boolean hasCustomContentToLeft() {                                                                  
 583          if (mLauncherCallbacks != null) {                                                                         
 584              return mLauncherCallbacks.hasCustomContentToLeft();                                                   
 585          }                                                                                                         
 586          return false;                                                                                             
 587      }                                                                                                             
 588                                                                                                                    
 589      /**                                                                                                           
 590       * To be overridden by subclasses to populate the custom content container and call                           
 591       * {@link #addToCustomContentPage}. This will only be invoked if                                              
 592       * {@link #hasCustomContentToLeft()} is {@code true}.                                                         
 593       */                                                                                                           
 594      protected void populateCustomContentContainer() {                                                             
 595          if (mLauncherCallbacks != null) {                                                                         
 596              mLauncherCallbacks.populateCustomContentContainer();                                                  
 597          }                                                                                                         
 598      }                                                                                                             
 599                                                                                                                    
 600      /**                                                                                                           
 601       * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to                   
 602       * ensure the custom content page is added or removed if necessary.                                           
 603       */                                                                                                           
 604      protected void invalidateHasCustomContentToLeft() {                                                           
 605          if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                                        
 606              // Not bound yet, wait for bindScreens to be called.                                                  
 607              return;                                                                                               
 608          }                                                                                                         
 609                                                                                                                    
 610          if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                         
 611              // Create the custom content page and call the subclass to populate it.                               
 612              mWorkspace.createCustomContentContainer();                                                            
 613              populateCustomContentContainer();                                                                     
 614          } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                                  
 615              mWorkspace.removeCustomContentPage();                                                                 
 616          }                                                                                                         
 617      }                                                                                                             
 618                                                                                                                    
 619 -    private void checkForLocaleChange() {                                                                         
 620 +    @Thunk void checkForLocaleChange() {                                                                          
 621          if (sLocaleConfiguration == null) {                                                                       
 622              new AsyncTask<Void, Void, LocaleConfiguration>() {                                                    
 623                  @Override                                                                                         
 624                  protected LocaleConfiguration doInBackground(Void... unused) {                                    
 625                      LocaleConfiguration localeConfiguration = new LocaleConfiguration();                          
 626                      readConfiguration(Launcher.this, localeConfiguration);                                        
 627                      return localeConfiguration;                                                                   
 628                  }                                                                                                 
 629                                                                                                                    
 630                  @Override                                                                                         
 631                  protected void onPostExecute(LocaleConfiguration result) {                                        
 632                      sLocaleConfiguration = result;                                                                
 633                      checkForLocaleChange();  // recursive, but now with a locale configuration                    
 634                  }                                                                                                 
 635              }.execute();                                                                                          
 636              return;                                                                                               
 637          }                                                                                                         
 638                                                                                                                    
 639          final Configuration configuration = getResources().getConfiguration();                                    
 640                                                                                                                    
 641          final String previousLocale = sLocaleConfiguration.locale;                                                
 642          final String locale = configuration.locale.toString();                                                    
 643                                                                                                                    
 644          final int previousMcc = sLocaleConfiguration.mcc;                                                         
 645          final int mcc = configuration.mcc;                                                                        
 646                                                                                                                    
 647          final int previousMnc = sLocaleConfiguration.mnc;                                                         
 648          final int mnc = configuration.mnc;                                                                        
 649                                                                                                                    
 650          boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;       
 651                                                                                                                    
 652          if (localeChanged) {                                                                                      
 653              sLocaleConfiguration.locale = locale;                                                                 
 654              sLocaleConfiguration.mcc = mcc;                                                                       
 655              sLocaleConfiguration.mnc = mnc;                                                                       
 656                                                                                                                    
 657              mIconCache.flush();                                                                                   
 658                                                                                                                    
 659              final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                                 
 660              new AsyncTask<Void, Void, Void>() {                                                                   
 661                  public Void doInBackground(Void ... args) {                                                       
 662                      writeConfiguration(Launcher.this, localeConfiguration);                                       
 663                      return null;                                                                                  
 664                  }                                                                                                 
 665              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
 666          }                                                                                                         
 667      }                                                                                                             
 668                                                                                                                    
 669 -    private static class LocaleConfiguration {                                                                    
 670 +    @Thunk static class LocaleConfiguration {                                                                     
 671          public String locale;                                                                                     
 672          public int mcc = -1;                                                                                      
 673          public int mnc = -1;                                                                                      
 674      }                                                                                                             
 675                                                                                                                    
 676 -    private static void readConfiguration(Context context, LocaleConfiguration configuration) {                   
 677 +    @Thunk static void readConfiguration(Context context, LocaleConfiguration configuration) {                    
 678          DataInputStream in = null;                                                                                
 679          try {                                                                                                     
 680              in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));                  
 681              configuration.locale = in.readUTF();                                                                  
 682              configuration.mcc = in.readInt();                                                                     
 683              configuration.mnc = in.readInt();                                                                     
 684          } catch (FileNotFoundException e) {                                                                       
 685              // Ignore                                                                                             
 686          } catch (IOException e) {                                                                                 
 687              // Ignore                                                                                             
 688          } finally {                                                                                               
 689              if (in != null) {                                                                                     
 690                  try {                                                                                             
 691                      in.close();                                                                                   
 692                  } catch (IOException e) {                                                                         
 693                      // Ignore                                                                                     
 694                  }                                                                                                 
 695              }                                                                                                     
 696          }                                                                                                         
 697      }                                                                                                             
 698                                                                                                                    
 699 -    private static void writeConfiguration(Context context, LocaleConfiguration configuration) {                  
 700 +    @Thunk static void writeConfiguration(Context context, LocaleConfiguration configuration) {                   
 701          DataOutputStream out = null;                                                                              
 702          try {                                                                                                     
 703              out = new DataOutputStream(context.openFileOutput(                                                    
 704                      LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                           
 705              out.writeUTF(configuration.locale);                                                                   
 706              out.writeInt(configuration.mcc);                                                                      
 707              out.writeInt(configuration.mnc);                                                                      
 708              out.flush();                                                                                          
 709          } catch (FileNotFoundException e) {                                                                       
 710              // Ignore                                                                                             
 711          } catch (IOException e) {                                                                                 
 712              //noinspection ResultOfMethodCallIgnored                                                              
 713              context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                               
 714          } finally {                                                                                               
 715              if (out != null) {                                                                                    
 716                  try {                                                                                             
 717                      out.close();                                                                                  
 718                  } catch (IOException e) {                                                                         
 719                      // Ignore                                                                                     
 720                  }                                                                                                 
 721              }                                                                                                     
 722          }                                                                                                         
 723      }                                                                                                             
 724                                                                                                                    
 725      public Stats getStats() {                                                                                     
 726          return mStats;                                                                                            
 727      }                                                                                                             
 728                                                                                                                    
 729      public LayoutInflater getInflater() {                                                                         
 730          return mInflater;                                                                                         
 731      }                                                                                                             
 732                                                                                                                    
 733 -    boolean isDraggingEnabled() {                                                                                 
 734 +    public boolean isDraggingEnabled() {                                                                          
 735          // We prevent dragging when we are loading the workspace as it is possible to pick up a view              
 736          // that is subsequently removed from the workspace in startBinding().                                     
 737          return !mModel.isLoadingWorkspace();                                                                      
 738      }                                                                                                             
 739                                                                                                                    
 740      @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                                
 741      public static int generateViewId() {                                                                          
 742          if (Build.VERSION.SDK_INT >= 17) {                                                                        
 743              return View.generateViewId();                                                                         
 744          } else {                                                                                                  
 745              // View.generateViewId() is not available. The following fallback logic is a copy                     
 746              // of its implementation.                                                                             
 747              for (;;) {                                                                                            
 748                  final int result = sNextGeneratedId.get();                                                        
 749                  // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                  
 750                  int newValue = result + 1;                                                                        
 751                  if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                
 752                  if (sNextGeneratedId.compareAndSet(result, newValue)) {                                           
 753                      return result;                                                                                
 754                  }                                                                                                 
 755              }                                                                                                     
 756          }                                                                                                         
 757      }                                                                                                             
 758                                                                                                                    
 759      public int getViewIdForItem(ItemInfo info) {                                                                  
 760          // This cast is safe given the > 2B range for int.                                                        
 761          int itemId = (int) info.id;                                                                               
 762          if (mItemIdToViewId.containsKey(itemId)) {                                                                
 763              return mItemIdToViewId.get(itemId);                                                                   
 764          }                                                                                                         
 765          int viewId = generateViewId();                                                                            
 766          mItemIdToViewId.put(itemId, viewId);                                                                      
 767          return viewId;                                                                                            
 768      }                                                                                                             
 769                                                                                                                    
 770      /**                                                                                                           
 771       * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have                  
 772       * a configuration step, this allows the proper animations to run after other transitions.                    
 773       */                                                                                                           
 774      private long completeAdd(PendingAddArguments args) {                                                          
 775          long screenId = args.screenId;                                                                            
 776          if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                                     
 777              // When the screen id represents an actual screen (as opposed to a rank) we make sure                 
 778              // that the drop page actually exists.                                                                
 779              screenId = ensurePendingDropLayoutExists(args.screenId);                                              
 780          }                                                                                                         
 781                                                                                                                    
 782          switch (args.requestCode) {                                                                               
 783              case REQUEST_CREATE_SHORTCUT:                                                                         
 784                  completeAddShortcut(args.intent, args.container, screenId, args.cellX,                            
 785                          args.cellY);                                                                              
 786                  break;                                                                                            
 787              case REQUEST_CREATE_APPWIDGET:                                                                        
 788                  completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);                     
 789                  break;                                                                                            
 790              case REQUEST_RECONFIGURE_APPWIDGET:                                                                   
 791                  completeRestoreAppWidget(args.appWidgetId);                                                       
 792                  break;                                                                                            
 793          }                                                                                                         
 794          // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,                   
 795          // if you turned the screen off and then back while in All Apps, Launcher would not                       
 796          // return to the workspace. Clearing mAddInfo.container here fixes this issue                             
 797          resetAddInfo();                                                                                           
 798          return screenId;                                                                                          
 799      }                                                                                                             
 800                                                                                                                    
 801      private void handleActivityResult(                                                                            
 802              final int requestCode, final int resultCode, final Intent data) {                                     
 803          // Reset the startActivity waiting flag                                                                   
 804          setWaitingForResult(false);                                                                               
 805          final int pendingAddWidgetId = mPendingAddWidgetId;                                                       
 806          mPendingAddWidgetId = -1;                                                                                 
 807                                                                                                                    
 808          Runnable exitSpringLoaded = new Runnable() {                                                              
 809              @Override                                                                                             
 810              public void run() {                                                                                   
 811                  exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                                  
 812                          EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                              
 813              }                                                                                                     
 814          };                                                                                                        
 815                                                                                                                    
 816          if (requestCode == REQUEST_BIND_APPWIDGET) {                                                              
 817              final int appWidgetId = data != null ?                                                                
 818                      data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                               
 819              if (resultCode == RESULT_CANCELED) {                                                                  
 820                  completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                         
 821                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 822                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 823              } else if (resultCode == RESULT_OK) {                                                                 
 824                  addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                              
 825                          mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                               
 826              }                                                                                                     
 827              return;                                                                                               
 828          } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                                       
 829              if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                                       
 830                  mWorkspace.exitOverviewMode(false);                                                               
 831              }                                                                                                     
 832              return;                                                                                               
 833          }                                                                                                         
 834                                                                                                                    
 835          boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                          
 836                  requestCode == REQUEST_CREATE_APPWIDGET);                                                         
 837                                                                                                                    
 838          final boolean workspaceLocked = isWorkspaceLocked();                                                      
 839          // We have special handling for widgets                                                                   
 840          if (isWidgetDrop) {                                                                                       
 841              final int appWidgetId;                                                                                
 842              int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)               
 843                      : -1;                                                                                         
 844              if (widgetId < 0) {                                                                                   
 845                  appWidgetId = pendingAddWidgetId;                                                                 
 846              } else {                                                                                              
 847                  appWidgetId = widgetId;                                                                           
 848              }                                                                                                     
 849                                                                                                                    
 850              final int result;                                                                                     
 851              if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                               
 852                  Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                                   
 853                          "returned from the widget configuration activity.");                                      
 854                  result = RESULT_CANCELED;                                                                         
 855                  completeTwoStageWidgetDrop(result, appWidgetId);                                                  
 856                  final Runnable onComplete = new Runnable() {                                                      
 857                      @Override                                                                                     
 858                      public void run() {                                                                           
 859                          exitSpringLoadedDragModeDelayed(false, 0, null);                                          
 860                      }                                                                                             
 861                  };                                                                                                
 862                  if (workspaceLocked) {                                                                            
 863                      // No need to remove the empty screen if we're mid-binding, as the                            
 864                      // the bind will not add the empty screen.                                                    
 865                      mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                       
 866                  } else {                                                                                          
 867                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 868                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 869                  }                                                                                                 
 870              } else {                                                                                              
 871                  if (!workspaceLocked) {                                                                           
 872                      if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {              
 873                          // When the screen id represents an actual screen (as opposed to a rank)                  
 874                          // we make sure that the drop page actually exists.                                       
 875                          mPendingAddInfo.screenId =                                                                
 876                                  ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                          
 877                      }                                                                                             
 878                      final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);           
 879                                                                                                                    
 880                      dropLayout.setDropPending(true);                                                              
 881                      final Runnable onComplete = new Runnable() {                                                  
 882                          @Override                                                                                 
 883                          public void run() {                                                                       
 884                              completeTwoStageWidgetDrop(resultCode, appWidgetId);                                  
 885                              dropLayout.setDropPending(false);                                                     
 886                          }                                                                                         
 887                      };                                                                                            
 888                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 889                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 890                  } else {                                                                                          
 891                      PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,              
 892                              mPendingAddInfo);                                                                     
 893                      sPendingAddItem = args;                                                                       
 894                  }                                                                                                 
 895              }                                                                                                     
 896              return;                                                                                               
 897          }                                                                                                         
 898                                                                                                                    
 899          if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                                       
 900              if (resultCode == RESULT_OK) {                                                                        
 901                  // Update the widget view.                                                                        
 902                  PendingAddArguments args = preparePendingAddArgs(requestCode, data,                               
 903                          pendingAddWidgetId, mPendingAddInfo);                                                     
 904                  if (workspaceLocked) {                                                                            
 905                      sPendingAddItem = args;                                                                       
 906                  } else {                                                                                          
 907                      completeAdd(args);                                                                            
 908                  }                                                                                                 
 909              }                                                                                                     
 910              // Leave the widget in the pending state if the user canceled the configure.                          
 911              return;                                                                                               
 912          }                                                                                                         
 913                                                                                                                    
 914          // The pattern used here is that a user PICKs a specific application,                                     
 915          // which, depending on the target, might need to CREATE the actual target.                                
 916                                                                                                                    
 917          // For example, the user would PICK_SHORTCUT for "Music playlist", and we                                 
 918          // launch over to the Music app to actually CREATE_SHORTCUT.                                              
 919          if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                             
 920              final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                         
 921                      mPendingAddInfo);                                                                             
 922              if (isWorkspaceLocked()) {                                                                            
 923                  sPendingAddItem = args;                                                                           
 924              } else {                                                                                              
 925                  completeAdd(args);                                                                                
 926                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 927                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 928              }                                                                                                     
 929          } else if (resultCode == RESULT_CANCELED) {                                                               
 930              mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                      
 931                      ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
 932          }                                                                                                         
 933          mDragLayer.clearAnimatedView();                                                                           
 934                                                                                                                    
 935      }                                                                                                             
 936                                                                                                                    
 937      @Override                                                                                                     
 938      protected void onActivityResult(                                                                              
 939              final int requestCode, final int resultCode, final Intent data) {                                     
 940          handleActivityResult(requestCode, resultCode, data);                                                      
 941          if (mLauncherCallbacks != null) {                                                                         
 942              mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                                   
 943          }                                                                                                         
 944      }                                                                                                             
 945                                                                                                                    
 946      private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                           
 947              appWidgetId, ItemInfo info) {                                                                         
 948          PendingAddArguments args = new PendingAddArguments();                                                     
 949          args.requestCode = requestCode;                                                                           
 950          args.intent = data;                                                                                       
 951          args.container = info.container;                                                                          
 952          args.screenId = info.screenId;                                                                            
 953          args.cellX = info.cellX;                                                                                  
 954          args.cellY = info.cellY;                                                                                  
 955          args.appWidgetId = appWidgetId;                                                                           
 956          return args;                                                                                              
 957      }                                                                                                             
 958                                                                                                                    
 959      /**                                                                                                           
 960       * Check to see if a given screen id exists. If not, create it at the end, return the new id.                 
 961       *                                                                                                            
 962       * @param screenId the screen id to check                                                                     
 963       * @return the new screen, or screenId if it exists                                                           
 964       */                                                                                                           
 965      private long ensurePendingDropLayoutExists(long screenId) {                                                   
 966          CellLayout dropLayout =                                                                                   
 967                  (CellLayout) mWorkspace.getScreenWithId(screenId);                                                
 968          if (dropLayout == null) {                                                                                 
 969              // it's possible that the add screen was removed because it was                                       
 970              // empty and a re-bind occurred                                                                       
 971              mWorkspace.addExtraEmptyScreen();                                                                     
 972              return mWorkspace.commitExtraEmptyScreen();                                                           
 973          } else {                                                                                                  
 974              return screenId;                                                                                      
 975          }                                                                                                         
 976      }                                                                                                             
 977                                                                                                                    
 978 -    private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                        
 979 +    @Thunk void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                         
 980          CellLayout cellLayout =                                                                                   
 981                  (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                                
 982          Runnable onCompleteRunnable = null;                                                                       
 983          int animationType = 0;                                                                                    
 984                                                                                                                    
 985          AppWidgetHostView boundWidget = null;                                                                     
 986          if (resultCode == RESULT_OK) {                                                                            
 987              animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                                   
 988              final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                         
 989                      mPendingAddWidgetInfo);                                                                       
 990              boundWidget = layout;                                                                                 
 991              onCompleteRunnable = new Runnable() {                                                                 
 992                  @Override                                                                                         
 993                  public void run() {                                                                               
 994                      completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                                  
 995                              mPendingAddInfo.screenId, layout, null);                                              
 996                      exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                              
 997                              EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                          
 998                  }                                                                                                 
 999              };                                                                                                    
1000          } else if (resultCode == RESULT_CANCELED) {                                                               
1001              mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                                        
1002              animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                                     
1003          }                                                                                                         
1004          if (mDragLayer.getAnimatedView() != null) {                                                               
1005              mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                             
1006                      (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                                  
1007                      animationType, boundWidget, true);                                                            
1008          } else if (onCompleteRunnable != null) {                                                                  
1009              // The animated view may be null in the case of a rotation during widget configuration                
1010              onCompleteRunnable.run();                                                                             
1011          }                                                                                                         
1012      }                                                                                                             
1013                                                                                                                    
1014      @Override                                                                                                     
1015      protected void onStop() {                                                                                     
1016          super.onStop();                                                                                           
1017          FirstFrameAnimatorHelper.setIsVisible(false);                                                             
1018                                                                                                                    
1019          if (mLauncherCallbacks != null) {                                                                         
1020              mLauncherCallbacks.onStop();                                                                          
1021          }                                                                                                         
1022      }                                                                                                             
1023                                                                                                                    
1024      @Override                                                                                                     
1025      protected void onStart() {                                                                                    
1026          super.onStart();                                                                                          
1027          FirstFrameAnimatorHelper.setIsVisible(true);                                                              
1028                                                                                                                    
1029          if (mLauncherCallbacks != null) {                                                                         
1030              mLauncherCallbacks.onStart();                                                                         
1031          }                                                                                                         
1032      }                                                                                                             
1033                                                                                                                    
1034      @Override                                                                                                     
1035      protected void onResume() {                                                                                   
1036          long startTime = 0;                                                                                       
1037          if (DEBUG_RESUME_TIME) {                                                                                  
1038              startTime = System.currentTimeMillis();                                                               
1039              Log.v(TAG, "Launcher.onResume()");                                                                    
1040          }                                                                                                         
1041                                                                                                                    
1042          if (mLauncherCallbacks != null) {                                                                         
1043              mLauncherCallbacks.preOnResume();                                                                     
1044          }                                                                                                         
1045                                                                                                                    
1046          super.onResume();                                                                                         
1047                                                                                                                    
1048          // Restore the previous launcher state                                                                    
1049          if (mOnResumeState == State.WORKSPACE) {                                                                  
1050              showWorkspace(false);                                                                                 
1051 -        } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                                      
1052 -            showAllApps(false, mAppsCustomizeContent.getContentType(), false);                                    
1053 +        } else if (mOnResumeState == State.APPS) {                                                                
1054 +            showAppsView(false /* animated */, false /* resetListToTop */);                                       
1055 +        } else if (mOnResumeState == State.WIDGETS) {                                                             
1056 +            showWidgetsView(false, false);                                                                        
1057          }                                                                                                         
1058          mOnResumeState = State.NONE;                                                                              
1059                                                                                                                    
1060          // Background was set to gradient in onPause(), restore to black if in all apps.                          
1061          setWorkspaceBackground(mState == State.WORKSPACE);                                                        
1062                                                                                                                    
1063          mPaused = false;                                                                                          
1064          if (mRestoring || mOnResumeNeedsLoad) {                                                                   
1065              setWorkspaceLoading(true);                                                                            
1066              mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                             
1067              mRestoring = false;                                                                                   
1068              mOnResumeNeedsLoad = false;                                                                           
1069          }                                                                                                         
1070          if (mBindOnResumeCallbacks.size() > 0) {                                                                  
1071              // We might have postponed some bind calls until onResume (see waitUntilResume) --                    
1072              // execute them here                                                                                  
1073              long startTimeCallbacks = 0;                                                                          
1074              if (DEBUG_RESUME_TIME) {                                                                              
1075                  startTimeCallbacks = System.currentTimeMillis();                                                  
1076              }                                                                                                     
1077                                                                                                                    
1078 -            if (mAppsCustomizeContent != null) {                                                                  
1079 -                mAppsCustomizeContent.setBulkBind(true);                                                          
1080 -            }                                                                                                     
1081              for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                             
1082                  mBindOnResumeCallbacks.get(i).run();                                                              
1083 -            }                                                                                                     
1084 -            if (mAppsCustomizeContent != null) {                                                                  
1085 -                mAppsCustomizeContent.setBulkBind(false);                                                         
1086              }                                                                                                     
1087              mBindOnResumeCallbacks.clear();                                                                       
1088              if (DEBUG_RESUME_TIME) {                                                                              
1089                  Log.d(TAG, "Time spent processing callbacks in onResume: " +                                      
1090                      (System.currentTimeMillis() - startTimeCallbacks));                                           
1091              }                                                                                                     
1092          }                                                                                                         
1093          if (mOnResumeCallbacks.size() > 0) {                                                                      
1094              for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                                 
1095                  mOnResumeCallbacks.get(i).run();                                                                  
1096              }                                                                                                     
1097              mOnResumeCallbacks.clear();                                                                           
1098          }                                                                                                         
1099                                                                                                                    
1100          // Reset the pressed state of icons that were locked in the press state while activities                  
1101          // were launching                                                                                         
1102          if (mWaitingForResume != null) {                                                                          
1103              // Resets the previous workspace icon press state                                                     
1104              mWaitingForResume.setStayPressed(false);                                                              
1105          }                                                                                                         
1106                                                                                                                    
1107          // It is possible that widgets can receive updates while launcher is not in the foreground.               
1108          // Consequently, the widgets will be inflated in the orientation of the foreground activity               
1109          // (framework issue). On resuming, we ensure that any widgets are inflated for the current                
1110          // orientation.                                                                                           
1111          getWorkspace().reinflateWidgetsIfNecessary();                                                             
1112 +        reinflateQSBIfNecessary();                                                                                
1113                                                                                                                    
1114          // Process any items that were added while Launcher was away.                                             
1115          InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                
1116                                                                                                                    
1117          if (DEBUG_RESUME_TIME) {                                                                                  
1118              Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));                    
1119          }                                                                                                         
1120                                                                                                                    
1121          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1122              // If we are resuming and the custom content is the current page, we call onShow().                   
1123              // It is also poassible that onShow will instead be called slightly after first layout                
1124              // if PagedView#setRestorePage was set to the custom content page in onCreate().                      
1125              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1126                  mWorkspace.getCustomContentCallbacks().onShow(true);                                              
1127              }                                                                                                     
1128          }                                                                                                         
1129          mWorkspace.updateInteractionForState();                                                                   
1130          mWorkspace.onResume();                                                                                    
1131                                                                                                                    
1132          PackageInstallerCompat.getInstance(this).onResume();                                                      
1133                                                                                                                    
1134          if (mLauncherCallbacks != null) {                                                                         
1135              mLauncherCallbacks.onResume();                                                                        
1136          }                                                                                                         
1137      }                                                                                                             
1138                                                                                                                    
1139      @Override                                                                                                     
1140      protected void onPause() {                                                                                    
1141          // Ensure that items added to Launcher are queued until Launcher returns                                  
1142          InstallShortcutReceiver.enableInstallQueue();                                                             
1143          PackageInstallerCompat.getInstance(this).onPause();                                                       
1144                                                                                                                    
1145          super.onPause();                                                                                          
1146          mPaused = true;                                                                                           
1147          mDragController.cancelDrag();                                                                             
1148          mDragController.resetLastGestureUpTime();                                                                 
1149                                                                                                                    
1150          // We call onHide() aggressively. The custom content callbacks should be able to                          
1151          // debounce excess onHide calls.                                                                          
1152          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1153              mWorkspace.getCustomContentCallbacks().onHide();                                                      
1154          }                                                                                                         
1155                                                                                                                    
1156          if (mLauncherCallbacks != null) {                                                                         
1157              mLauncherCallbacks.onPause();                                                                         
1158          }                                                                                                         
1159      }                                                                                                             
1160                                                                                                                    
1161      public interface CustomContentCallbacks {                                                                     
1162          // Custom content is completely shown. {@code fromResume} indicates whether this was caused               
1163          // by a onResume or by scrolling otherwise.                                                               
1164          public void onShow(boolean fromResume);                                                                   
1165                                                                                                                    
1166          // Custom content is completely hidden                                                                    
1167          public void onHide();                                                                                     
1168                                                                                                                    
1169          // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).                     
1170          public void onScrollProgressChanged(float progress);                                                      
1171                                                                                                                    
1172          // Indicates whether the user is allowed to scroll away from the custom content.                          
1173          boolean isScrollingAllowed();                                                                             
1174      }                                                                                                             
1175                                                                                                                    
1176      public interface LauncherOverlay {                                                                            
1177                                                                                                                    
1178          /**                                                                                                       
1179           * Touch interaction leading to overscroll has begun                                                      
1180           */                                                                                                       
1181          public void onScrollInteractionBegin();                                                                   
1182                                                                                                                    
1183          /**                                                                                                       
1184           * Touch interaction related to overscroll has ended                                                      
1185           */                                                                                                       
1186          public void onScrollInteractionEnd();                                                                     
1187                                                                                                                    
1188          /**                                                                                                       
1189           * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                          
1190           * screen (or in the case of RTL, the rightmost screen).                                                  
1191           */                                                                                                       
1192          public void onScrollChange(int progress, boolean rtl);                                                    
1193                                                                                                                    
1194          /**                                                                                                       
1195           * Screen has stopped scrolling                                                                           
1196           */                                                                                                       
1197          public void onScrollSettled();                                                                            
1198                                                                                                                    
1199          /**                                                                                                       
1200           * This method can be called by the Launcher in order to force the LauncherOverlay                        
1201           * to exit fully immersive mode.                                                                          
1202           */                                                                                                       
1203          public void forceExitFullImmersion();                                                                     
1204 +    }                                                                                                             
1205 +                                                                                                                  
1206 +    public interface LauncherAppsCallbacks {                                                                      
1207 +        /**                                                                                                       
1208 +         * Updates launcher to the available space that AllApps can take so as not to overlap with                
1209 +         * any other views.                                                                                       
1210 +         */                                                                                                       
1211 +        public void onAllAppsBoundsChanged(Rect bounds);                                                          
1212 +                                                                                                                  
1213 +        /**                                                                                                       
1214 +         * Called to dismiss all apps if it is showing.                                                           
1215 +         */                                                                                                       
1216 +        public void dismissAllApps();                                                                             
1217      }                                                                                                             
1218                                                                                                                    
1219      public interface LauncherOverlayCallbacks {                                                                   
1220          /**                                                                                                       
1221           * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,                    
1222           * however it doesn't modify any state within the launcher.                                               
1223           */                                                                                                       
1224          public boolean canEnterFullImmersion();                                                                   
1225                                                                                                                    
1226          /**                                                                                                       
1227           * Should be called to tell Launcher that the LauncherOverlay will take over interaction,                 
1228           * eg. by occupying the full screen and handling all touch events.                                        
1229           *                                                                                                        
1230           * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this                 
1231           *          case, Launcher will modify any necessary state and assumes the overlay is                     
1232           *          handling all interaction. If false, the LauncherOverlay should cancel any                     
1233           *                                                                                                        
1234           */                                                                                                       
1235          public boolean enterFullImmersion();                                                                      
1236                                                                                                                    
1237          /**                                                                                                       
1238           * Must be called when exiting fully immersive mode. Indicates to Launcher that it has                    
1239           * full control over UI and state.                                                                        
1240           */                                                                                                       
1241          public void exitFullImmersion();                                                                          
1242      }                                                                                                             
1243                                                                                                                    
1244      class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                                      
1245                                                                                                                    
1246          @Override                                                                                                 
1247          public boolean canEnterFullImmersion() {                                                                  
1248              return mState == State.WORKSPACE;                                                                     
1249          }                                                                                                         
1250                                                                                                                    
1251          @Override                                                                                                 
1252          public boolean enterFullImmersion() {                                                                     
1253              if (mState == State.WORKSPACE) {                                                                      
1254                  // When fully immersed, disregard any touches which fall through.                                 
1255                  mDragLayer.setBlockTouch(true);                                                                   
1256                  return true;                                                                                      
1257              }                                                                                                     
1258              return false;                                                                                         
1259          }                                                                                                         
1260                                                                                                                    
1261          @Override                                                                                                 
1262          public void exitFullImmersion() {                                                                         
1263              mDragLayer.setBlockTouch(false);                                                                      
1264          }                                                                                                         
1265      }                                                                                                             
1266                                                                                                                    
1267      protected boolean hasSettings() {                                                                             
1268          if (mLauncherCallbacks != null) {                                                                         
1269              return mLauncherCallbacks.hasSettings();                                                              
1270          }                                                                                                         
1271          return false;                                                                                             
1272      }                                                                                                             
1273                                                                                                                    
1274                                                                                                                    
1275      public void addToCustomContentPage(View customContent,                                                        
1276              CustomContentCallbacks callbacks, String description) {                                               
1277          mWorkspace.addToCustomContentPage(customContent, callbacks, description);                                 
1278      }                                                                                                             
1279                                                                                                                    
1280      // The custom content needs to offset its content to account for the QSB                                      
1281      public int getTopOffsetForCustomContent() {                                                                   
1282          return mWorkspace.getPaddingTop();                                                                        
1283      }                                                                                                             
1284                                                                                                                    
1285      @Override                                                                                                     
1286      public Object onRetainNonConfigurationInstance() {                                                            
1287          // Flag the loader to stop early before switching                                                         
1288          if (mModel.isCurrentCallbacks(this)) {                                                                    
1289              mModel.stopLoader();                                                                                  
1290          }                                                                                                         
1291 -        if (mAppsCustomizeContent != null) {                                                                      
1292 -            mAppsCustomizeContent.surrender();                                                                    
1293 -        }                                                                                                         
1294 +        //TODO(hyunyoungs): stop the widgets loader when there is a rotation.                                     
1295 +                                                                                                                  
1296          return Boolean.TRUE;                                                                                      
1297      }                                                                                                             
1298                                                                                                                    
1299      // We can't hide the IME if it was forced open.  So don't bother                                              
1300      @Override                                                                                                     
1301      public void onWindowFocusChanged(boolean hasFocus) {                                                          
1302          super.onWindowFocusChanged(hasFocus);                                                                     
1303          mHasFocus = hasFocus;                                                                                     
1304                                                                                                                    
1305          if (mLauncherCallbacks != null) {                                                                         
1306              mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                                    
1307          }                                                                                                         
1308      }                                                                                                             
1309                                                                                                                    
1310      private boolean acceptFilter() {                                                                              
1311          final InputMethodManager inputManager = (InputMethodManager)                                              
1312                  getSystemService(Context.INPUT_METHOD_SERVICE);                                                   
1313          return !inputManager.isFullscreenMode();                                                                  
1314      }                                                                                                             
1315                                                                                                                    
1316      @Override                                                                                                     
1317      public boolean onKeyDown(int keyCode, KeyEvent event) {                                                       
1318          final int uniChar = event.getUnicodeChar();                                                               
1319          final boolean handled = super.onKeyDown(keyCode, event);                                                  
1320          final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);                       
1321          if (!handled && acceptFilter() && isKeyNotWhitespace) {                                                   
1322              boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,                  
1323                      keyCode, event);                                                                              
1324              if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                                
1325                  // something usable has been typed - start a search                                               
1326                  // the typed text will be retrieved and cleared by                                                
1327                  // showSearchDialog()                                                                             
1328                  // If there are multiple keystrokes before the search dialog takes focus,                         
1329                  // onSearchRequested() will be called for every keystroke,                                        
1330                  // but it is idempotent, so it's fine.                                                            
1331                  return onSearchRequested();                                                                       
1332              }                                                                                                     
1333          }                                                                                                         
1334                                                                                                                    
1335          // Eat the long press event so the keyboard doesn't come up.                                              
1336          if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                            
1337              return true;                                                                                          
1338          }                                                                                                         
1339                                                                                                                    
1340          return handled;                                                                                           
1341      }                                                                                                             
1342                                                                                                                    
1343      private String getTypedText() {                                                                               
1344          return mDefaultKeySsb.toString();                                                                         
1345      }                                                                                                             
1346                                                                                                                    
1347      private void clearTypedText() {                                                                               
1348          mDefaultKeySsb.clear();                                                                                   
1349          mDefaultKeySsb.clearSpans();                                                                              
1350          Selection.setSelection(mDefaultKeySsb, 0);                                                                
1351      }                                                                                                             
1352                                                                                                                    
1353      /**                                                                                                           
1354       * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type               
1355       * State                                                                                                      
1356       */                                                                                                           
1357      private static State intToState(int stateOrdinal) {                                                           
1358          State state = State.WORKSPACE;                                                                            
1359          final State[] stateValues = State.values();                                                               
1360          for (int i = 0; i < stateValues.length; i++) {                                                            
1361              if (stateValues[i].ordinal() == stateOrdinal) {                                                       
1362                  state = stateValues[i];                                                                           
1363                  break;                                                                                            
1364              }                                                                                                     
1365          }                                                                                                         
1366          return state;                                                                                             
1367      }                                                                                                             
1368                                                                                                                    
1369      /**                                                                                                           
1370       * Restores the previous state, if it exists.                                                                 
1371       *                                                                                                            
1372       * @param savedState The previous state.                                                                      
1373       */                                                                                                           
1374      @SuppressWarnings("unchecked")                                                                                
1375      private void restoreState(Bundle savedState) {                                                                
1376          if (savedState == null) {                                                                                 
1377              return;                                                                                               
1378          }                                                                                                         
1379                                                                                                                    
1380          State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));                    
1381 -        if (state == State.APPS_CUSTOMIZE) {                                                                      
1382 -            mOnResumeState = State.APPS_CUSTOMIZE;                                                                
1383 +        if (state == State.APPS || state == State.WIDGETS) {                                                      
1384 +            mOnResumeState = state;                                                                               
1385          }                                                                                                         
1386                                                                                                                    
1387          int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                                       
1388                  PagedView.INVALID_RESTORE_PAGE);                                                                  
1389          if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                                    
1390              mWorkspace.setRestorePage(currentScreen);                                                             
1391          }                                                                                                         
1392                                                                                                                    
1393          final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);             
1394          final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);                   
1395                                                                                                                    
1396          if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                                     
1397              mPendingAddInfo.container = pendingAddContainer;                                                      
1398              mPendingAddInfo.screenId = pendingAddScreen;                                                          
1399              mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                          
1400              mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                          
1401              mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                          
1402              mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                          
1403              AppWidgetProviderInfo info = savedState.getParcelable(                                                
1404                      RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);                                                       
1405              mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this, info);                   
1406              mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                         
1407              setWaitingForResult(true);                                                                            
1408              mRestoring = true;                                                                                    
1409          }                                                                                                         
1410                                                                                                                    
1411          boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);                 
1412          if (renameFolder) {                                                                                       
1413              long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                                 
1414              mFolderInfo = mModel.getFolderById(this, sFolders, id);                                               
1415              mRestoring = true;                                                                                    
1416          }                                                                                                         
1417                                                                                                                    
1418 -        // Restore the AppsCustomize tab                                                                          
1419 -        if (mAppsCustomizeTabHost != null) {                                                                      
1420 -            String curTab = savedState.getString("apps_customize_currentTab");                                    
1421 -            if (curTab != null) {                                                                                 
1422 -                mAppsCustomizeTabHost.setContentTypeImmediate(                                                    
1423 -                        mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                                   
1424 -                mAppsCustomizeContent.loadAssociatedPages(                                                        
1425 -                        mAppsCustomizeContent.getCurrentPage());                                                  
1426 -            }                                                                                                     
1427 -                                                                                                                  
1428 -            int currentIndex = savedState.getInt("apps_customize_currentIndex");                                  
1429 -            mAppsCustomizeContent.restorePageForIndex(currentIndex);                                              
1430 -        }                                                                                                         
1431          mItemIdToViewId = (HashMap<Integer, Integer>)                                                             
1432                  savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                               
1433      }                                                                                                             
1434                                                                                                                    
1435      /**                                                                                                           
1436       * Finds all the views we need and configure them properly.                                                   
1437       */                                                                                                           
1438      private void setupViews() {                                                                                   
1439          final DragController dragController = mDragController;                                                    
1440                                                                                                                    
1441          mLauncherView = findViewById(R.id.launcher);                                                              
1442          mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                                  
1443          mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                                   
1444          mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                         
1445          mWorkspace.setPageSwitchListener(this);                                                                   
1446          mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                           
1447                                                                                                                    
1448          mLauncherView.setSystemUiVisibility(                                                                      
1449                  View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);              
1450          mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);                       
1451                                                                                                                    
1452          // Setup the drag layer                                                                                   
1453          mDragLayer.setup(this, dragController);                                                                   
1454                                                                                                                    
1455          // Setup the hotseat                                                                                      
1456          mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                          
1457          if (mHotseat != null) {                                                                                   
1458              mHotseat.setup(this);                                                                                 
1459              mHotseat.setOnLongClickListener(this);                                                                
1460          }                                                                                                         
1461                                                                                                                    
1462          mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                           
1463          View widgetButton = findViewById(R.id.widget_button);                                                     
1464          widgetButton.setOnClickListener(new OnClickListener() {                                                   
1465              @Override                                                                                             
1466              public void onClick(View arg0) {                                                                      
1467                  if (!mWorkspace.isSwitchingState()) {                                                             
1468                      onClickAddWidgetButton(arg0);                                                                 
1469                  }                                                                                                 
1470              }                                                                                                     
1471          });                                                                                                       
1472          widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                                        
1473                                                                                                                    
1474          View wallpaperButton = findViewById(R.id.wallpaper_button);                                               
1475          wallpaperButton.setOnClickListener(new OnClickListener() {                                                
1476              @Override                                                                                             
1477              public void onClick(View arg0) {                                                                      
1478                  if (!mWorkspace.isSwitchingState()) {                                                             
1479                      onClickWallpaperPicker(arg0);                                                                 
1480                  }                                                                                                 
1481              }                                                                                                     
1482          });                                                                                                       
1483          wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                                     
1484                                                                                                                    
1485          View settingsButton = findViewById(R.id.settings_button);                                                 
1486          if (hasSettings()) {                                                                                      
1487              settingsButton.setOnClickListener(new OnClickListener() {                                             
1488                  @Override                                                                                         
1489                  public void onClick(View arg0) {                                                                  
1490                      if (!mWorkspace.isSwitchingState()) {                                                         
1491                          onClickSettingsButton(arg0);                                                              
1492                      }                                                                                             
1493                  }                                                                                                 
1494              });                                                                                                   
1495              settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                                  
1496          } else {                                                                                                  
1497              settingsButton.setVisibility(View.GONE);                                                              
1498          }                                                                                                         
1499                                                                                                                    
1500          mOverviewPanel.setAlpha(0f);                                                                              
1501                                                                                                                    
1502          // Setup the workspace                                                                                    
1503          mWorkspace.setHapticFeedbackEnabled(false);                                                               
1504          mWorkspace.setOnLongClickListener(this);                                                                  
1505          mWorkspace.setup(dragController);                                                                         
1506          dragController.addDragListener(mWorkspace);                                                               
1507                                                                                                                    
1508          // Get the search/delete bar                                                                              
1509          mSearchDropTargetBar = (SearchDropTargetBar)                                                              
1510                  mDragLayer.findViewById(R.id.search_drop_target_bar);                                             
1511                                                                                                                    
1512 +        // Setup Apps                                                                                             
1513 +        mAppsView = (AppsContainerView) findViewById(R.id.apps_view);                                             
1514 +        if (mLauncherCallbacks != null && mLauncherCallbacks.overrideAllAppsSearch()) {                           
1515 +            mAppsView.hideSearchBar();                                                                            
1516 +        }                                                                                                         
1517 +                                                                                                                  
1518          // Setup AppsCustomize                                                                                    
1519 -        mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);                    
1520 -        mAppsCustomizeContent = (AppsCustomizePagedView)                                                          
1521 -                mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                             
1522 -        mAppsCustomizeContent.setup(this, dragController);                                                        
1523 +        mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);                                    
1524                                                                                                                    
1525          // Setup the drag controller (drop targets have to be added in reverse order in priority)                 
1526          dragController.setDragScoller(mWorkspace);                                                                
1527          dragController.setScrollView(mDragLayer);                                                                 
1528          dragController.setMoveTarget(mWorkspace);                                                                 
1529          dragController.addDropTarget(mWorkspace);                                                                 
1530          if (mSearchDropTargetBar != null) {                                                                       
1531              mSearchDropTargetBar.setup(this, dragController);                                                     
1532 -            mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                    
1533 +            mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                            
1534          }                                                                                                         
1535                                                                                                                    
1536          if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                             
1537              Log.v(TAG, "adding WeightWatcher");                                                                   
1538              mWeightWatcher = new WeightWatcher(this);                                                             
1539              mWeightWatcher.setAlpha(0.5f);                                                                        
1540              ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                                 
1541                      new FrameLayout.LayoutParams(                                                                 
1542                              FrameLayout.LayoutParams.MATCH_PARENT,                                                
1543                              FrameLayout.LayoutParams.WRAP_CONTENT,                                                
1544                              Gravity.BOTTOM)                                                                       
1545              );                                                                                                    
1546                                                                                                                    
1547              boolean show = shouldShowWeightWatcher();                                                             
1548              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
1549          }                                                                                                         
1550      }                                                                                                             
1551                                                                                                                    
1552      /**                                                                                                           
1553       * Sets the all apps button. This method is called from {@link Hotseat}.                                      
1554       */                                                                                                           
1555      public void setAllAppsButton(View allAppsButton) {                                                            
1556          mAllAppsButton = allAppsButton;                                                                           
1557      }                                                                                                             
1558                                                                                                                    
1559      public View getAllAppsButton() {                                                                              
1560          return mAllAppsButton;                                                                                    
1561      }                                                                                                             
1562                                                                                                                    
1563      /**                                                                                                           
1564       * Creates a view representing a shortcut.                                                                    
1565       *                                                                                                            
1566       * @param info The data structure describing the shortcut.                                                    
1567       *                                                                                                            
1568       * @return A View inflated from R.layout.application.                                                         
1569       */                                                                                                           
1570      View createShortcut(ShortcutInfo info) {                                                                      
1571          return createShortcut(R.layout.application,                                                               
1572                  (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                            
1573      }                                                                                                             
1574                                                                                                                    
1575      /**                                                                                                           
1576       * Creates a view representing a shortcut inflated from the specified resource.                               
1577       *                                                                                                            
1578       * @param layoutResId The id of the XML layout used to create the shortcut.                                   
1579       * @param parent The group the shortcut belongs to.                                                           
1580       * @param info The data structure describing the shortcut.                                                    
1581       *                                                                                                            
1582       * @return A View inflated from layoutResId.                                                                  
1583       */                                                                                                           
1584      public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                            
1585          BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);                 
1586          favorite.applyFromShortcutInfo(info, mIconCache, true);                                                   
1587          favorite.setOnClickListener(this);                                                                        
1588          favorite.setOnFocusChangeListener(mFocusHandler);                                                         
1589          return favorite;                                                                                          
1590      }                                                                                                             
1591                                                                                                                    
1592      /**                                                                                                           
1593       * Add a shortcut to the workspace.                                                                           
1594       *                                                                                                            
1595       * @param data The intent describing the shortcut.                                                            
1596       * @param cellInfo The position on screen where to create the shortcut.                                       
1597       */                                                                                                           
1598      private void completeAddShortcut(Intent data, long container, long screenId, int cellX,                       
1599              int cellY) {                                                                                          
1600          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1601          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1602          CellLayout layout = getCellLayout(container, screenId);                                                   
1603                                                                                                                    
1604          boolean foundCellSpan = false;                                                                            
1605                                                                                                                    
1606          ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                            
1607          if (info == null) {                                                                                       
1608              return;                                                                                               
1609          }                                                                                                         
1610          final View view = createShortcut(info);                                                                   
1611                                                                                                                    
1612          // First we check if we already know the exact location where we want to add this item.                   
1613          if (cellX >= 0 && cellY >= 0) {                                                                           
1614              cellXY[0] = cellX;                                                                                    
1615              cellXY[1] = cellY;                                                                                    
1616              foundCellSpan = true;                                                                                 
1617                                                                                                                    
1618              // If appropriate, either create a folder or add to an existing folder                                
1619              if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,                        
1620                      true, null,null)) {                                                                           
1621                  return;                                                                                           
1622              }                                                                                                     
1623              DragObject dragObject = new DragObject();                                                             
1624              dragObject.dragInfo = info;                                                                           
1625              if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,                    
1626                      true)) {                                                                                      
1627                  return;                                                                                           
1628              }                                                                                                     
1629          } else if (touchXY != null) {                                                                             
1630              // when dragging and dropping, just find the closest free spot                                        
1631              int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);                    
1632              foundCellSpan = (result != null);                                                                     
1633          } else {                                                                                                  
1634              foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                                 
1635          }                                                                                                         
1636                                                                                                                    
1637          if (!foundCellSpan) {                                                                                     
1638              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1639              return;                                                                                               
1640          }                                                                                                         
1641                                                                                                                    
1642 -        LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);            
1643 +        LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1]);                   
1644                                                                                                                    
1645          if (!mRestoring) {                                                                                        
1646              mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                         
1647                      isWorkspaceLocked());                                                                         
1648          }                                                                                                         
1649      }                                                                                                             
1650                                                                                                                    
1651      static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                         
1652              int minHeight) {                                                                                      
1653          Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);                    
1654          // We want to account for the extra amount of padding that we are adding to the widget                    
1655          // to ensure that it gets the full amount of space that it has requested                                  
1656          int requiredWidth = minWidth + padding.left + padding.right;                                              
1657          int requiredHeight = minHeight + padding.top + padding.bottom;                                            
1658          return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                                        
1659      }                                                                                                             
1660                                                                                                                    
1661      static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                                  
1662          return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                           
1663      }                                                                                                             
1664                                                                                                                    
1665      static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                               
1666          return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);               
1667      }                                                                                                             
1668                                                                                                                    
1669      static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                                   
1670          return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);                      
1671      }                                                                                                             
1672                                                                                                                    
1673      static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                                
1674          return getSpanForWidget(context, info.componentName, info.minResizeWidth,                                 
1675                  info.minResizeHeight);                                                                            
1676      }                                                                                                             
1677                                                                                                                    
1678      /**                                                                                                           
1679       * Add a widget to the workspace.                                                                             
1680       *                                                                                                            
1681       * @param appWidgetId The app widget id                                                                       
1682       */                                                                                                           
1683 -    private void completeAddAppWidget(int appWidgetId, long container, long screenId,                             
1684 +    @Thunk void completeAddAppWidget(int appWidgetId, long container, long screenId,                              
1685              AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                            
1686                                                                                                                    
1687          ItemInfo info = mPendingAddInfo;                                                                          
1688          if (appWidgetInfo == null) {                                                                              
1689              appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                                  
1690                      mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                             
1691          }                                                                                                         
1692                                                                                                                    
1693          if (appWidgetInfo.isCustomWidget) {                                                                       
1694              appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                                 
1695          }                                                                                                         
1696                                                                                                                    
1697          LauncherAppWidgetInfo launcherInfo;                                                                       
1698          launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                            
1699          launcherInfo.spanX = info.spanX;                                                                          
1700          launcherInfo.spanY = info.spanY;                                                                          
1701          launcherInfo.minSpanX = info.minSpanX;                                                                    
1702          launcherInfo.minSpanY = info.minSpanY;                                                                    
1703          launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                             
1704                                                                                                                    
1705          LauncherModel.addItemToDatabase(this, launcherInfo,                                                       
1706 -                container, screenId, info.cellX, info.cellY, false);                                              
1707 +                container, screenId, info.cellX, info.cellY);                                                     
1708                                                                                                                    
1709          if (!mRestoring) {                                                                                        
1710              if (hostView == null) {                                                                               
1711                  // Perform actual inflation because we're live                                                    
1712                  launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                              
1713                          appWidgetInfo);                                                                           
1714              } else {                                                                                              
1715                  // The AppWidgetHostView has already been inflated and instantiated                               
1716                  launcherInfo.hostView = hostView;                                                                 
1717              }                                                                                                     
1718              launcherInfo.hostView.setTag(launcherInfo);                                                           
1719              launcherInfo.hostView.setVisibility(View.VISIBLE);                                                    
1720              launcherInfo.notifyWidgetSizeChanged(this);                                                           
1721                                                                                                                    
1722              mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,                        
1723                      info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                     
1724                                                                                                                    
1725              addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                                 
1726          }                                                                                                         
1727          resetAddInfo();                                                                                           
1728      }                                                                                                             
1729                                                                                                                    
1730      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                         
1731          @Override                                                                                                 
1732          public void onReceive(Context context, Intent intent) {                                                   
1733              final String action = intent.getAction();                                                             
1734              if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                                        
1735                  mUserPresent = false;                                                                             
1736                  mDragLayer.clearAllResizeFrames();                                                                
1737 -                updateRunning();                                                                                  
1738 +                updateAutoAdvanceState();                                                                         
1739                                                                                                                    
1740                  // Reset AllApps to its initial state only if we are not in the middle of                         
1741                  // processing a multi-step drop                                                                   
1742 -                if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {               
1743 +                if (mAppsView != null && mWidgetsView != null &&                                                  
1744 +                        mPendingAddInfo.container == ItemInfo.NO_ID) {                                            
1745                      showWorkspace(false);                                                                         
1746                  }                                                                                                 
1747              } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                               
1748                  mUserPresent = true;                                                                              
1749 -                updateRunning();                                                                                  
1750 +                updateAutoAdvanceState();                                                                         
1751              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {                     
1752                  mModel.resetLoadedState(false, true);                                                             
1753                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1754                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                               
1755              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {                    
1756                  mModel.resetLoadedState(false, true);                                                             
1757                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1758                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                                 
1759                                  | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                                   
1760              } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                             
1761                      || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {                        
1762                  getModel().forceReload();                                                                         
1763              }                                                                                                     
1764          }                                                                                                         
1765      };                                                                                                            
1766                                                                                                                    
1767      @Override                                                                                                     
1768      public void onAttachedToWindow() {                                                                            
1769          super.onAttachedToWindow();                                                                               
1770                                                                                                                    
1771          // Listen for broadcasts related to user-presence                                                         
1772          final IntentFilter filter = new IntentFilter();                                                           
1773          filter.addAction(Intent.ACTION_SCREEN_OFF);                                                               
1774          filter.addAction(Intent.ACTION_USER_PRESENT);                                                             
1775          // For handling managed profiles                                                                          
1776          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                                        
1777          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                                      
1778          if (ENABLE_DEBUG_INTENTS) {                                                                               
1779              filter.addAction(DebugIntents.DELETE_DATABASE);                                                       
1780              filter.addAction(DebugIntents.MIGRATE_DATABASE);                                                      
1781          }                                                                                                         
1782          registerReceiver(mReceiver, filter);                                                                      
1783          FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                              
1784          setupTransparentSystemBarsForLmp();                                                                       
1785          mAttached = true;                                                                                         
1786          mVisible = true;                                                                                          
1787      }                                                                                                             
1788                                                                                                                    
1789      /**                                                                                                           
1790       * Sets up transparent navigation and status bars in LMP.                                                     
1791       * This method is a no-op for other platform versions.                                                        
1792       */                                                                                                           
1793 -    @TargetApi(19)                                                                                                
1794 +    @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                                      
1795      private void setupTransparentSystemBarsForLmp() {                                                             
1796 -        // TODO(sansid): use the APIs directly when compiling against L sdk.                                      
1797 -        // Currently we use reflection to access the flags and the API to set the transparency                    
1798 -        // on the System bars.                                                                                    
1799          if (Utilities.isLmpOrAbove()) {                                                                           
1800 -            try {                                                                                                 
1801 -                getWindow().getAttributes().systemUiVisibility |=                                                 
1802 -                        (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                        
1803 -                                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                           
1804 -                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                    
1805 -                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1806 -                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                
1807 -                Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(                       
1808 -                        "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                                     
1809 -                getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                                      
1810 -                                                                                                                  
1811 -                Method setStatusBarColorMethod =                                                                  
1812 -                        Window.class.getDeclaredMethod("setStatusBarColor", int.class);                           
1813 -                Method setNavigationBarColorMethod =                                                              
1814 -                        Window.class.getDeclaredMethod("setNavigationBarColor", int.class);                       
1815 -                setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                                   
1816 -                setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                               
1817 -            } catch (NoSuchFieldException e) {                                                                    
1818 -                Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                             
1819 -            } catch (NoSuchMethodException ex) {                                                                  
1820 -                Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                            
1821 -            } catch (IllegalAccessException e) {                                                                  
1822 -                Log.w(TAG, "IllegalAccessException while setting up transparent bars");                           
1823 -            } catch (IllegalArgumentException e) {                                                                
1824 -                Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                         
1825 -            } catch (InvocationTargetException e) {                                                               
1826 -                Log.w(TAG, "InvocationTargetException while setting up transparent bars");                        
1827 -            } finally {}                                                                                          
1828 +            Window window = getWindow();                                                                          
1829 +            window.getAttributes().systemUiVisibility |=                                                          
1830 +                    (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                            
1831 +                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                               
1832 +                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                        
1833 +            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                                  
1834 +                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                    
1835 +            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);                        
1836 +            window.setStatusBarColor(Color.TRANSPARENT);                                                          
1837 +            window.setNavigationBarColor(Color.TRANSPARENT);                                                      
1838          }                                                                                                         
1839      }                                                                                                             
1840                                                                                                                    
1841      @Override                                                                                                     
1842      public void onDetachedFromWindow() {                                                                          
1843          super.onDetachedFromWindow();                                                                             
1844          mVisible = false;                                                                                         
1845                                                                                                                    
1846          if (mAttached) {                                                                                          
1847              unregisterReceiver(mReceiver);                                                                        
1848              mAttached = false;                                                                                    
1849          }                                                                                                         
1850 -        updateRunning();                                                                                          
1851 +        updateAutoAdvanceState();                                                                                 
1852      }                                                                                                             
1853                                                                                                                    
1854      public void onWindowVisibilityChanged(int visibility) {                                                       
1855          mVisible = visibility == View.VISIBLE;                                                                    
1856 -        updateRunning();                                                                                          
1857 +        updateAutoAdvanceState();                                                                                 
1858          // The following code used to be in onResume, but it turns out onResume is called when                    
1859          // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged                    
1860          // is a more appropriate event to handle                                                                  
1861          if (mVisible) {                                                                                           
1862 -            mAppsCustomizeTabHost.onWindowVisible();                                                              
1863              if (!mWorkspaceLoading) {                                                                             
1864                  final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                               
1865                  // We want to let Launcher draw itself at least once before we force it to build                  
1866                  // layers on all the workspace pages, so that transitioning to Launcher from other                
1867                  // apps is nice and speedy.                                                                       
1868                  observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                                
1869                      private boolean mStarted = false;                                                             
1870                      public void onDraw() {                                                                        
1871                          if (mStarted) return;                                                                     
1872                          mStarted = true;                                                                          
1873                          // We delay the layer building a bit in order to give                                     
1874                          // other message processing a time to run.  In particular                                 
1875                          // this avoids a delay in hiding the IME if it was                                        
1876                          // currently shown, because doing that may involve                                        
1877                          // some communication back with the app.                                                  
1878                          mWorkspace.postDelayed(mBuildLayersRunnable, 500);                                        
1879                          final ViewTreeObserver.OnDrawListener listener = this;                                    
1880                          mWorkspace.post(new Runnable() {                                                          
1881                                  public void run() {                                                               
1882                                      if (mWorkspace != null &&                                                     
1883                                              mWorkspace.getViewTreeObserver() != null) {                           
1884                                          mWorkspace.getViewTreeObserver().                                         
1885                                                  removeOnDrawListener(listener);                                   
1886                                      }                                                                             
1887                                  }                                                                                 
1888                              });                                                                                   
1889                          return;                                                                                   
1890                      }                                                                                             
1891                  });                                                                                               
1892              }                                                                                                     
1893              clearTypedText();                                                                                     
1894          }                                                                                                         
1895      }                                                                                                             
1896                                                                                                                    
1897 -    private void sendAdvanceMessage(long delay) {                                                                 
1898 +    @Thunk void sendAdvanceMessage(long delay) {                                                                  
1899          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1900          Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                                        
1901          mHandler.sendMessageDelayed(msg, delay);                                                                  
1902          mAutoAdvanceSentTime = System.currentTimeMillis();                                                        
1903      }                                                                                                             
1904                                                                                                                    
1905 -    private void updateRunning() {                                                                                
1906 +    @Thunk void updateAutoAdvanceState() {                                                                        
1907          boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();                    
1908          if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                          
1909              mAutoAdvanceRunning = autoAdvanceRunning;                                                             
1910              if (autoAdvanceRunning) {                                                                             
1911                  long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;                
1912                  sendAdvanceMessage(delay);                                                                        
1913              } else {                                                                                              
1914                  if (!mWidgetsToAdvance.isEmpty()) {                                                               
1915                      mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                         
1916                              (System.currentTimeMillis() - mAutoAdvanceSentTime));                                 
1917                  }                                                                                                 
1918                  mHandler.removeMessages(ADVANCE_MSG);                                                             
1919                  mHandler.removeMessages(0); // Remove messages sent using postDelayed()                           
1920              }                                                                                                     
1921          }                                                                                                         
1922      }                                                                                                             
1923                                                                                                                    
1924      private final Handler mHandler = new Handler() {                                                              
1925          @Override                                                                                                 
1926          public void handleMessage(Message msg) {                                                                  
1927              if (msg.what == ADVANCE_MSG) {                                                                        
1928                  int i = 0;                                                                                        
1929                  for (View key: mWidgetsToAdvance.keySet()) {                                                      
1930                      final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);                
1931                      final int delay = mAdvanceStagger * i;                                                        
1932                      if (v instanceof Advanceable) {                                                               
1933                         postDelayed(new Runnable() {                                                               
1934                             public void run() {                                                                    
1935                                 ((Advanceable) v).advance();                                                       
1936                             }                                                                                      
1937                         }, delay);                                                                                 
1938                      }                                                                                             
1939                      i++;                                                                                          
1940                  }                                                                                                 
1941                  sendAdvanceMessage(mAdvanceInterval);                                                             
1942              }                                                                                                     
1943          }                                                                                                         
1944      };                                                                                                            
1945                                                                                                                    
1946      void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {                     
1947          if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                               
1948          View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                          
1949          if (v instanceof Advanceable) {                                                                           
1950              mWidgetsToAdvance.put(hostView, appWidgetInfo);                                                       
1951              ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                                      
1952 -            updateRunning();                                                                                      
1953 +            updateAutoAdvanceState();                                                                             
1954          }                                                                                                         
1955      }                                                                                                             
1956                                                                                                                    
1957      void removeWidgetToAutoAdvance(View hostView) {                                                               
1958          if (mWidgetsToAdvance.containsKey(hostView)) {                                                            
1959              mWidgetsToAdvance.remove(hostView);                                                                   
1960 -            updateRunning();                                                                                      
1961 +            updateAutoAdvanceState();                                                                             
1962          }                                                                                                         
1963      }                                                                                                             
1964                                                                                                                    
1965      public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                             
1966          removeWidgetToAutoAdvance(launcherInfo.hostView);                                                         
1967          launcherInfo.hostView = null;                                                                             
1968      }                                                                                                             
1969                                                                                                                    
1970 -    void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                         
1971 +    public void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                  
1972          int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);                    
1973          Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                                        
1974      }                                                                                                             
1975                                                                                                                    
1976 -    public ArrayList<AppInfo> getAllAppsList() {                                                                  
1977 -        return mAppsCustomizeContent.getApps();                                                                   
1978 -    }                                                                                                             
1979 -                                                                                                                  
1980      public DragLayer getDragLayer() {                                                                             
1981          return mDragLayer;                                                                                        
1982 +    }                                                                                                             
1983 +                                                                                                                  
1984 +    public AppsContainerView getAppsView() {                                                                      
1985 +        return mAppsView;                                                                                         
1986 +    }                                                                                                             
1987 +                                                                                                                  
1988 +    public WidgetsContainerView getWidgetsView() {                                                                
1989 +        return mWidgetsView;                                                                                      
1990      }                                                                                                             
1991                                                                                                                    
1992      public Workspace getWorkspace() {                                                                             
1993          return mWorkspace;                                                                                        
1994      }                                                                                                             
1995                                                                                                                    
1996      public Hotseat getHotseat() {                                                                                 
1997          return mHotseat;                                                                                          
1998      }                                                                                                             
1999                                                                                                                    
2000      public ViewGroup getOverviewPanel() {                                                                         
2001          return mOverviewPanel;                                                                                    
2002      }                                                                                                             
2003                                                                                                                    
2004      public SearchDropTargetBar getSearchBar() {                                                                   
2005          return mSearchDropTargetBar;                                                                              
2006      }                                                                                                             
2007                                                                                                                    
2008      public LauncherAppWidgetHost getAppWidgetHost() {                                                             
2009          return mAppWidgetHost;                                                                                    
2010      }                                                                                                             
2011                                                                                                                    
2012      public LauncherModel getModel() {                                                                             
2013          return mModel;                                                                                            
2014      }                                                                                                             
2015                                                                                                                    
2016      protected SharedPreferences getSharedPrefs() {                                                                
2017          return mSharedPrefs;                                                                                      
2018      }                                                                                                             
2019                                                                                                                    
2020      public void closeSystemDialogs() {                                                                            
2021          getWindow().closeAllPanels();                                                                             
2022                                                                                                                    
2023          // Whatever we were doing is hereby canceled.                                                             
2024          setWaitingForResult(false);                                                                               
2025      }                                                                                                             
2026                                                                                                                    
2027      @Override                                                                                                     
2028      protected void onNewIntent(Intent intent) {                                                                   
2029          long startTime = 0;                                                                                       
2030          if (DEBUG_RESUME_TIME) {                                                                                  
2031              startTime = System.currentTimeMillis();                                                               
2032          }                                                                                                         
2033          super.onNewIntent(intent);                                                                                
2034                                                                                                                    
2035          // Close the menu                                                                                         
2036          if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                                      
2037              // also will cancel mWaitingForResult.                                                                
2038              closeSystemDialogs();                                                                                 
2039                                                                                                                    
2040              final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                                      
2041                      Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                                        
2042                      != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                                    
2043                                                                                                                    
2044              if (mWorkspace == null) {                                                                             
2045                  // Can be cases where mWorkspace is null, this prevents a NPE                                     
2046                  return;                                                                                           
2047              }                                                                                                     
2048              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2049              // In all these cases, only animate if we're already on home                                          
2050              mWorkspace.exitWidgetResizeMode();                                                                    
2051                                                                                                                    
2052              boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                            
2053                      mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                            
2054              if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&                      
2055                      openFolder == null && moveToDefaultScreen) {                                                  
2056                  mWorkspace.moveToDefaultScreen(true);                                                             
2057              }                                                                                                     
2058                                                                                                                    
2059              closeFolder();                                                                                        
2060              exitSpringLoadedDragMode();                                                                           
2061                                                                                                                    
2062              // If we are already on home, then just animate back to the workspace,                                
2063              // otherwise, just wait until onResume to set the state back to Workspace                             
2064              if (alreadyOnHome) {                                                                                  
2065                  showWorkspace(true);                                                                              
2066              } else {                                                                                              
2067                  mOnResumeState = State.WORKSPACE;                                                                 
2068              }                                                                                                     
2069                                                                                                                    
2070              final View v = getWindow().peekDecorView();                                                           
2071              if (v != null && v.getWindowToken() != null) {                                                        
2072                  InputMethodManager imm = (InputMethodManager)getSystemService(                                    
2073                          INPUT_METHOD_SERVICE);                                                                    
2074                  imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                               
2075              }                                                                                                     
2076                                                                                                                    
2077 -            // Reset the apps customize page                                                                      
2078 -            if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                                
2079 -                mAppsCustomizeTabHost.reset();                                                                    
2080 +            // Reset the apps view                                                                                
2081 +            if (!alreadyOnHome && mAppsView != null) {                                                            
2082 +                mAppsView.scrollToTop();                                                                          
2083 +            }                                                                                                     
2084 +                                                                                                                  
2085 +            // Reset the widgets view                                                                             
2086 +            if (!alreadyOnHome && mWidgetsView != null) {                                                         
2087 +                mWidgetsView.scrollToTop();                                                                       
2088              }                                                                                                     
2089                                                                                                                    
2090              if (mLauncherCallbacks != null) {                                                                     
2091                  mLauncherCallbacks.onHomeIntent();                                                                
2092              }                                                                                                     
2093          }                                                                                                         
2094                                                                                                                    
2095          if (DEBUG_RESUME_TIME) {                                                                                  
2096              Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));                 
2097          }                                                                                                         
2098                                                                                                                    
2099          if (mLauncherCallbacks != null) {                                                                         
2100              mLauncherCallbacks.onNewIntent(intent);                                                               
2101          }                                                                                                         
2102      }                                                                                                             
2103                                                                                                                    
2104      @Override                                                                                                     
2105      public void onRestoreInstanceState(Bundle state) {                                                            
2106          super.onRestoreInstanceState(state);                                                                      
2107          for (int page: mSynchronouslyBoundPages) {                                                                
2108              mWorkspace.restoreInstanceStateForChild(page);                                                        
2109          }                                                                                                         
2110      }                                                                                                             
2111                                                                                                                    
2112      @Override                                                                                                     
2113      protected void onSaveInstanceState(Bundle outState) {                                                         
2114          if (mWorkspace.getChildCount() > 0) {                                                                     
2115              outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                         
2116                      mWorkspace.getCurrentPageOffsetFromCustomContent());                                          
2117          }                                                                                                         
2118          super.onSaveInstanceState(outState);                                                                      
2119                                                                                                                    
2120          outState.putInt(RUNTIME_STATE, mState.ordinal());                                                         
2121          // We close any open folder since it will not be re-opened, and we need to make sure                      
2122          // this state is reflected.                                                                               
2123          closeFolder();                                                                                            
2124                                                                                                                    
2125          if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&                       
2126                  mWaitingForResult) {                                                                              
2127              outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);                     
2128              outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                         
2129              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                             
2130              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                             
2131              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                             
2132              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                             
2133              outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);                 
2134              outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                            
2135          }                                                                                                         
2136                                                                                                                    
2137          if (mFolderInfo != null && mWaitingForResult) {                                                           
2138              outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                                       
2139              outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                             
2140          }                                                                                                         
2141                                                                                                                    
2142 -        // Save the current AppsCustomize tab                                                                     
2143 -        if (mAppsCustomizeTabHost != null) {                                                                      
2144 -            AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();                     
2145 -            String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                           
2146 -            if (currentTabTag != null) {                                                                          
2147 -                outState.putString("apps_customize_currentTab", currentTabTag);                                   
2148 -            }                                                                                                     
2149 -            int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                                 
2150 -            outState.putInt("apps_customize_currentIndex", currentIndex);                                         
2151 -        }                                                                                                         
2152 +        // Save the current widgets tray?                                                                         
2153 +        // TODO(hyunyoungs)                                                                                       
2154          outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                                        
2155                                                                                                                    
2156          if (mLauncherCallbacks != null) {                                                                         
2157              mLauncherCallbacks.onSaveInstanceState(outState);                                                     
2158          }                                                                                                         
2159      }                                                                                                             
2160                                                                                                                    
2161      @Override                                                                                                     
2162      public void onDestroy() {                                                                                     
2163          super.onDestroy();                                                                                        
2164                                                                                                                    
2165          // Remove all pending runnables                                                                           
2166          mHandler.removeMessages(ADVANCE_MSG);                                                                     
2167          mHandler.removeMessages(0);                                                                               
2168          mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                         
2169                                                                                                                    
2170          // Stop callbacks from LauncherModel                                                                      
2171          LauncherAppState app = (LauncherAppState.getInstance());                                                  
2172                                                                                                                    
2173          // It's possible to receive onDestroy after a new Launcher activity has                                   
2174          // been created. In this case, don't interfere with the new Launcher.                                     
2175          if (mModel.isCurrentCallbacks(this)) {                                                                    
2176              mModel.stopLoader();                                                                                  
2177              app.setLauncher(null);                                                                                
2178          }                                                                                                         
2179                                                                                                                    
2180          try {                                                                                                     
2181              mAppWidgetHost.stopListening();                                                                       
2182          } catch (NullPointerException ex) {                                                                       
2183              Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);                   
2184          }                                                                                                         
2185          mAppWidgetHost = null;                                                                                    
2186                                                                                                                    
2187          mWidgetsToAdvance.clear();                                                                                
2188                                                                                                                    
2189          TextKeyListener.getInstance().release();                                                                  
2190                                                                                                                    
2191          // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace               
2192          // to prevent leaking Launcher activities on orientation change.                                          
2193          if (mModel != null) {                                                                                     
2194              mModel.unbindItemInfosAndClearQueuedBindRunnables();                                                  
2195          }                                                                                                         
2196                                                                                                                    
2197          getContentResolver().unregisterContentObserver(mWidgetObserver);                                          
2198          unregisterReceiver(mCloseSystemDialogsReceiver);                                                          
2199                                                                                                                    
2200          mDragLayer.clearAllResizeFrames();                                                                        
2201          ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                                    
2202          mWorkspace.removeAllWorkspaceScreens();                                                                   
2203          mWorkspace = null;                                                                                        
2204          mDragController = null;                                                                                   
2205                                                                                                                    
2206          LauncherAnimUtils.onDestroyActivity();                                                                    
2207                                                                                                                    
2208          if (mLauncherCallbacks != null) {                                                                         
2209              mLauncherCallbacks.onDestroy();                                                                       
2210          }                                                                                                         
2211      }                                                                                                             
2212                                                                                                                    
2213      public DragController getDragController() {                                                                   
2214          return mDragController;                                                                                   
2215      }                                                                                                             
2216                                                                                                                    
2217      @Override                                                                                                     
2218      public void startActivityForResult(Intent intent, int requestCode) {                                          
2219          onStartForResult(requestCode);                                                                            
2220          super.startActivityForResult(intent, requestCode);                                                        
2221      }                                                                                                             
2222                                                                                                                    
2223      @Override                                                                                                     
2224      public void startIntentSenderForResult (IntentSender intent, int requestCode,                                 
2225              Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {                
2226          onStartForResult(requestCode);                                                                            
2227          try {                                                                                                     
2228              super.startIntentSenderForResult(intent, requestCode,                                                 
2229                  fillInIntent, flagsMask, flagsValues, extraFlags, options);                                       
2230          } catch (IntentSender.SendIntentException e) {                                                            
2231              throw new ActivityNotFoundException();                                                                
2232          }                                                                                                         
2233      }                                                                                                             
2234                                                                                                                    
2235      private void onStartForResult(int requestCode) {                                                              
2236          if (requestCode >= 0) {                                                                                   
2237              setWaitingForResult(true);                                                                            
2238          }                                                                                                         
2239      }                                                                                                             
2240                                                                                                                    
2241      /**                                                                                                           
2242       * Indicates that we want global search for this activity by setting the globalSearch                         
2243       * argument for {@link #startSearch} to true.                                                                 
2244       */                                                                                                           
2245      @Override                                                                                                     
2246      public void startSearch(String initialQuery, boolean selectInitialQuery,                                      
2247              Bundle appSearchData, boolean globalSearch) {                                                         
2248                                                                                                                    
2249          showWorkspace(true);                                                                                      
2250                                                                                                                    
2251          if (initialQuery == null) {                                                                               
2252              // Use any text typed in the launcher as the initial query                                            
2253              initialQuery = getTypedText();                                                                        
2254          }                                                                                                         
2255          if (appSearchData == null) {                                                                              
2256              appSearchData = new Bundle();                                                                         
2257              appSearchData.putString("source", "launcher-search");                                                 
2258          }                                                                                                         
2259          Rect sourceBounds = new Rect();                                                                           
2260          if (mSearchDropTargetBar != null) {                                                                       
2261              sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                             
2262          }                                                                                                         
2263                                                                                                                    
2264          boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                              
2265                  appSearchData, sourceBounds);                                                                     
2266          if (clearTextImmediately) {                                                                               
2267              clearTypedText();                                                                                     
2268          }                                                                                                         
2269      }                                                                                                             
2270                                                                                                                    
2271      /**                                                                                                           
2272       * Start a text search.                                                                                       
2273       *                                                                                                            
2274       * @return {@code true} if the search will start immediately, so any further keypresses                       
2275       * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue               
2276       * to buffer keypresses.                                                                                      
2277       */                                                                                                           
2278      public boolean startSearch(String initialQuery,                                                               
2279              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2280          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
2281              return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,                
2282                      sourceBounds);                                                                                
2283          }                                                                                                         
2284                                                                                                                    
2285          startGlobalSearch(initialQuery, selectInitialQuery,                                                       
2286                  appSearchData, sourceBounds);                                                                     
2287          return false;                                                                                             
2288      }                                                                                                             
2289                                                                                                                    
2290      /**                                                                                                           
2291       * Starts the global search activity. This code is a copied from SearchManager                                
2292       */                                                                                                           
2293      private void startGlobalSearch(String initialQuery,                                                           
2294              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2295          final SearchManager searchManager =                                                                       
2296              (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                             
2297          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
2298          if (globalSearchActivity == null) {                                                                       
2299              Log.w(TAG, "No global search activity found.");                                                       
2300              return;                                                                                               
2301          }                                                                                                         
2302          Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                                    
2303          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2304          intent.setComponent(globalSearchActivity);                                                                
2305          // Make sure that we have a Bundle to put source in                                                       
2306          if (appSearchData == null) {                                                                              
2307              appSearchData = new Bundle();                                                                         
2308          } else {                                                                                                  
2309              appSearchData = new Bundle(appSearchData);                                                            
2310          }                                                                                                         
2311          // Set source to package name of app that starts global search if not set already.                        
2312          if (!appSearchData.containsKey("source")) {                                                               
2313              appSearchData.putString("source", getPackageName());                                                  
2314          }                                                                                                         
2315          intent.putExtra(SearchManager.APP_DATA, appSearchData);                                                   
2316          if (!TextUtils.isEmpty(initialQuery)) {                                                                   
2317              intent.putExtra(SearchManager.QUERY, initialQuery);                                                   
2318          }                                                                                                         
2319          if (selectInitialQuery) {                                                                                 
2320              intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                                
2321          }                                                                                                         
2322          intent.setSourceBounds(sourceBounds);                                                                     
2323          try {                                                                                                     
2324              startActivity(intent);                                                                                
2325          } catch (ActivityNotFoundException ex) {                                                                  
2326              Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                              
2327          }                                                                                                         
2328      }                                                                                                             
2329                                                                                                                    
2330      public boolean isOnCustomContent() {                                                                          
2331          return mWorkspace.isOnOrMovingToCustomContent();                                                          
2332      }                                                                                                             
2333                                                                                                                    
2334      @Override                                                                                                     
2335      public boolean onPrepareOptionsMenu(Menu menu) {                                                              
2336          super.onPrepareOptionsMenu(menu);                                                                         
2337          if (!isOnCustomContent()) {                                                                               
2338              // Close any open folders                                                                             
2339              closeFolder();                                                                                        
2340              // Stop resizing any widgets                                                                          
2341              mWorkspace.exitWidgetResizeMode();                                                                    
2342              if (!mWorkspace.isInOverviewMode()) {                                                                 
2343                  // Show the overview mode                                                                         
2344                  showOverviewMode(true);                                                                           
2345              } else {                                                                                              
2346                  showWorkspace(true);                                                                              
2347              }                                                                                                     
2348          }                                                                                                         
2349          if (mLauncherCallbacks != null) {                                                                         
2350              return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                                 
2351          }                                                                                                         
2352                                                                                                                    
2353          return false;                                                                                             
2354      }                                                                                                             
2355                                                                                                                    
2356      @Override                                                                                                     
2357      public boolean onSearchRequested() {                                                                          
2358          startSearch(null, false, null, true);                                                                     
2359          // Use a custom animation for launching search                                                            
2360          return true;                                                                                              
2361      }                                                                                                             
2362                                                                                                                    
2363      public boolean isWorkspaceLocked() {                                                                          
2364          return mWorkspaceLoading || mWaitingForResult;                                                            
2365      }                                                                                                             
2366                                                                                                                    
2367      public boolean isWorkspaceLoading() {                                                                         
2368          return mWorkspaceLoading;                                                                                 
2369      }                                                                                                             
2370                                                                                                                    
2371      private void setWorkspaceLoading(boolean value) {                                                             
2372          boolean isLocked = isWorkspaceLocked();                                                                   
2373          mWorkspaceLoading = value;                                                                                
2374          if (isLocked != isWorkspaceLocked()) {                                                                    
2375              onWorkspaceLockedChanged();                                                                           
2376          }                                                                                                         
2377      }                                                                                                             
2378                                                                                                                    
2379      private void setWaitingForResult(boolean value) {                                                             
2380          boolean isLocked = isWorkspaceLocked();                                                                   
2381          mWaitingForResult = value;                                                                                
2382          if (isLocked != isWorkspaceLocked()) {                                                                    
2383              onWorkspaceLockedChanged();                                                                           
2384          }                                                                                                         
2385      }                                                                                                             
2386                                                                                                                    
2387      protected void onWorkspaceLockedChanged() {                                                                   
2388          if (mLauncherCallbacks != null) {                                                                         
2389              mLauncherCallbacks.onWorkspaceLockedChanged();                                                        
2390          }                                                                                                         
2391      }                                                                                                             
2392                                                                                                                    
2393      private void resetAddInfo() {                                                                                 
2394          mPendingAddInfo.container = ItemInfo.NO_ID;                                                               
2395          mPendingAddInfo.screenId = -1;                                                                            
2396          mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                                       
2397          mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                                       
2398          mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                                 
2399          mPendingAddInfo.dropPos = null;                                                                           
2400      }                                                                                                             
2401                                                                                                                    
2402      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                                       
2403              AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {                   
2404          addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                                       
2405      }                                                                                                             
2406                                                                                                                    
2407      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2408              final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,               
2409              int delay) {                                                                                          
2410          if (appWidgetInfo.configure != null) {                                                                    
2411              mPendingAddWidgetInfo = appWidgetInfo;                                                                
2412              mPendingAddWidgetId = appWidgetId;                                                                    
2413                                                                                                                    
2414              // Launch over to configure widget, if needed                                                         
2415              mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                               
2416                      mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                                    
2417                                                                                                                    
2418          } else {                                                                                                  
2419              // Otherwise just add it                                                                              
2420              Runnable onComplete = new Runnable() {                                                                
2421                  @Override                                                                                         
2422                  public void run() {                                                                               
2423                      // Exit spring loaded mode if necessary after adding the widget                               
2424                      exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,                   
2425                              null);                                                                                
2426                  }                                                                                                 
2427              };                                                                                                    
2428              completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                         
2429                      appWidgetInfo);                                                                               
2430              mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                             
2431          }                                                                                                         
2432      }                                                                                                             
2433                                                                                                                    
2434      protected void moveToCustomContentScreen(boolean animate) {                                                   
2435          // Close any folders that may be open.                                                                    
2436          closeFolder();                                                                                            
2437          mWorkspace.moveToCustomContentScreen(animate);                                                            
2438      }                                                                                                             
2439                                                                                                                    
2440      public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                            
2441              int[] cell, int spanX, int spanY) {                                                                   
2442          switch (info.itemType) {                                                                                  
2443              case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                           
2444              case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                                  
2445                  int span[] = new int[2];                                                                          
2446                  span[0] = spanX;                                                                                  
2447                  span[1] = spanY;                                                                                  
2448                  addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                                 
2449                          container, screenId, cell, span);                                                         
2450                  break;                                                                                            
2451              case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                                   
2452                  processShortcutFromDrop(info.componentName, container, screenId, cell);                           
2453                  break;                                                                                            
2454              default:                                                                                              
2455                  throw new IllegalStateException("Unknown item type: " + info.itemType);                           
2456              }                                                                                                     
2457      }                                                                                                             
2458                                                                                                                    
2459      /**                                                                                                           
2460       * Process a shortcut drop.                                                                                   
2461       *                                                                                                            
2462       * @param componentName The name of the component                                                             
2463       * @param screenId The ID of the screen where it should be added                                              
2464       * @param cell The cell it should be added to, optional                                                       
2465       */                                                                                                           
2466      private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,              
2467              int[] cell) {                                                                                         
2468          resetAddInfo();                                                                                           
2469          mPendingAddInfo.container = container;                                                                    
2470          mPendingAddInfo.screenId = screenId;                                                                      
2471          mPendingAddInfo.dropPos = null;                                                                           
2472                                                                                                                    
2473          if (cell != null) {                                                                                       
2474              mPendingAddInfo.cellX = cell[0];                                                                      
2475              mPendingAddInfo.cellY = cell[1];                                                                      
2476          }                                                                                                         
2477                                                                                                                    
2478          Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                                  
2479          createShortcutIntent.setComponent(componentName);                                                         
2480          processShortcut(createShortcutIntent);                                                                    
2481      }                                                                                                             
2482                                                                                                                    
2483      /**                                                                                                           
2484       * Process a widget drop.                                                                                     
2485       *                                                                                                            
2486       * @param info The PendingAppWidgetInfo of the widget being added.                                            
2487       * @param screenId The ID of the screen where it should be added                                              
2488       * @param cell The cell it should be added to, optional                                                       
2489       */                                                                                                           
2490      private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                   
2491              int[] cell, int[] span) {                                                                             
2492          resetAddInfo();                                                                                           
2493          mPendingAddInfo.container = info.container = container;                                                   
2494          mPendingAddInfo.screenId = info.screenId = screenId;                                                      
2495          mPendingAddInfo.dropPos = null;                                                                           
2496          mPendingAddInfo.minSpanX = info.minSpanX;                                                                 
2497          mPendingAddInfo.minSpanY = info.minSpanY;                                                                 
2498                                                                                                                    
2499          if (cell != null) {                                                                                       
2500              mPendingAddInfo.cellX = cell[0];                                                                      
2501              mPendingAddInfo.cellY = cell[1];                                                                      
2502          }                                                                                                         
2503          if (span != null) {                                                                                       
2504              mPendingAddInfo.spanX = span[0];                                                                      
2505              mPendingAddInfo.spanY = span[1];                                                                      
2506          }                                                                                                         
2507                                                                                                                    
2508          AppWidgetHostView hostView = info.boundWidget;                                                            
2509          int appWidgetId;                                                                                          
2510          if (hostView != null) {                                                                                   
2511              appWidgetId = hostView.getAppWidgetId();                                                              
2512              addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                             
2513          } else {                                                                                                  
2514              // In this case, we either need to start an activity to get permission to bind                        
2515              // the widget, or we need to start an activity to configure the widget, or both.                      
2516              appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                               
2517              Bundle options = info.bindOptions;                                                                    
2518                                                                                                                    
2519              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
2520                      appWidgetId, info.info, options);                                                             
2521              if (success) {                                                                                        
2522                  addAppWidgetImpl(appWidgetId, info, null, info.info);                                             
2523              } else {                                                                                              
2524                  mPendingAddWidgetInfo = info.info;                                                                
2525                  Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                               
2526                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                
2527                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);                   
2528                  mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                                  
2529                      .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);                      
2530                  // TODO: we need to make sure that this accounts for the options bundle.                          
2531                  // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                            
2532                  startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                           
2533              }                                                                                                     
2534          }                                                                                                         
2535      }                                                                                                             
2536                                                                                                                    
2537      void processShortcut(Intent intent) {                                                                         
2538          Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                            
2539      }                                                                                                             
2540                                                                                                                    
2541      void processWallpaper(Intent intent) {                                                                        
2542          startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                                   
2543      }                                                                                                             
2544                                                                                                                    
2545      FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,                       
2546              int cellY) {                                                                                          
2547          final FolderInfo folderInfo = new FolderInfo();                                                           
2548          folderInfo.title = getText(R.string.folder_name);                                                         
2549                                                                                                                    
2550          // Update the model                                                                                       
2551 -        LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,             
2552 -                false);                                                                                           
2553 +        LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId,                           
2554 +                cellX, cellY);                                                                                    
2555          sFolders.put(folderInfo.id, folderInfo);                                                                  
2556                                                                                                                    
2557          // Create the view                                                                                        
2558          FolderIcon newFolder =                                                                                    
2559              FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);                       
2560          mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                                
2561                  isWorkspaceLocked());                                                                             
2562          // Force measure the new folder icon                                                                      
2563          CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                                     
2564          parent.getShortcutsAndWidgets().measureChild(newFolder);                                                  
2565          return newFolder;                                                                                         
2566      }                                                                                                             
2567                                                                                                                    
2568      void removeFolder(FolderInfo folder) {                                                                        
2569          sFolders.remove(folder.id);                                                                               
2570 -    }                                                                                                             
2571 -                                                                                                                  
2572 -    protected ComponentName getWallpaperPickerComponent() {                                                       
2573 -        if (mLauncherCallbacks != null) {                                                                         
2574 -            return mLauncherCallbacks.getWallpaperPickerComponent();                                              
2575 -        }                                                                                                         
2576 -        return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());              
2577      }                                                                                                             
2578                                                                                                                    
2579      /**                                                                                                           
2580       * Registers various content observers. The current implementation registers                                  
2581       * only a favorites observer to keep track of the favorites applications.                                     
2582       */                                                                                                           
2583      private void registerContentObservers() {                                                                     
2584          ContentResolver resolver = getContentResolver();                                                          
2585          resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                            
2586                  true, mWidgetObserver);                                                                           
2587      }                                                                                                             
2588                                                                                                                    
2589      @Override                                                                                                     
2590      public boolean dispatchKeyEvent(KeyEvent event) {                                                             
2591          if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                          
2592              switch (event.getKeyCode()) {                                                                         
2593                  case KeyEvent.KEYCODE_HOME:                                                                       
2594                      return true;                                                                                  
2595                  case KeyEvent.KEYCODE_VOLUME_DOWN:                                                                
2596                      if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                       
2597                          dumpState();                                                                              
2598                          return true;                                                                              
2599                      }                                                                                             
2600                      break;                                                                                        
2601              }                                                                                                     
2602          } else if (event.getAction() == KeyEvent.ACTION_UP) {                                                     
2603              switch (event.getKeyCode()) {                                                                         
2604                  case KeyEvent.KEYCODE_HOME:                                                                       
2605                      return true;                                                                                  
2606              }                                                                                                     
2607          }                                                                                                         
2608                                                                                                                    
2609          return super.dispatchKeyEvent(event);                                                                     
2610      }                                                                                                             
2611                                                                                                                    
2612      @Override                                                                                                     
2613      public void onBackPressed() {                                                                                 
2614          if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                               
2615              return;                                                                                               
2616          }                                                                                                         
2617                                                                                                                    
2618 -        if (isAllAppsVisible()) {                                                                                 
2619 -            if (mAppsCustomizeContent.getContentType() ==                                                         
2620 -                    AppsCustomizePagedView.ContentType.Applications) {                                            
2621 -                showWorkspace(true);                                                                              
2622 -            } else {                                                                                              
2623 -                showOverviewMode(true);                                                                           
2624 -            }                                                                                                     
2625 +        LauncherAccessibilityDelegate delegate =                                                                  
2626 +                LauncherAppState.getInstance().getAccessibilityDelegate();                                        
2627 +        if (delegate != null && delegate.onBackPressed()) {                                                       
2628 +            return;                                                                                               
2629 +        }                                                                                                         
2630 +                                                                                                                  
2631 +        if (isAppsViewVisible()) {                                                                                
2632 +            showWorkspace(true);                                                                                  
2633 +        } else if (isWidgetsViewVisible())  {                                                                     
2634 +            showOverviewMode(true);                                                                               
2635          } else if (mWorkspace.isInOverviewMode()) {                                                               
2636              mWorkspace.exitOverviewMode(true);                                                                    
2637          } else if (mWorkspace.getOpenFolder() != null) {                                                          
2638              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2639              if (openFolder.isEditingName()) {                                                                     
2640                  openFolder.dismissEditingName();                                                                  
2641              } else {                                                                                              
2642                  closeFolder();                                                                                    
2643              }                                                                                                     
2644          } else {                                                                                                  
2645              mWorkspace.exitWidgetResizeMode();                                                                    
2646                                                                                                                    
2647              // Back button is a no-op here, but give at least some feedback for the button press                  
2648              mWorkspace.showOutlinesTemporarily();                                                                 
2649          }                                                                                                         
2650      }                                                                                                             
2651                                                                                                                    
2652      /**                                                                                                           
2653       * Re-listen when widgets are reset.                                                                          
2654       */                                                                                                           
2655 -    private void onAppWidgetReset() {                                                                             
2656 +    @Thunk void onAppWidgetReset() {                                                                              
2657          if (mAppWidgetHost != null) {                                                                             
2658              mAppWidgetHost.startListening();                                                                      
2659          }                                                                                                         
2660      }                                                                                                             
2661                                                                                                                    
2662      /**                                                                                                           
2663       * Launches the intent referred by the clicked shortcut.                                                      
2664       *                                                                                                            
2665       * @param v The view representing the clicked shortcut.                                                       
2666       */                                                                                                           
2667      public void onClick(View v) {                                                                                 
2668          // Make sure that rogue clicks don't get through while allapps is launching, or after the                 
2669          // view has detached (it's possible for this to happen if the view is removed mid touch).                 
2670          if (v.getWindowToken() == null) {                                                                         
2671              return;                                                                                               
2672          }                                                                                                         
2673                                                                                                                    
2674          if (!mWorkspace.isFinishedSwitchingState()) {                                                             
2675              return;                                                                                               
2676          }                                                                                                         
2677                                                                                                                    
2678          if (v instanceof Workspace) {                                                                             
2679              if (mWorkspace.isInOverviewMode()) {                                                                  
2680                  mWorkspace.exitOverviewMode(true);                                                                
2681              }                                                                                                     
2682              return;                                                                                               
2683          }                                                                                                         
2684                                                                                                                    
2685          if (v instanceof CellLayout) {                                                                            
2686              if (mWorkspace.isInOverviewMode()) {                                                                  
2687                  mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                                    
2688              }                                                                                                     
2689          }                                                                                                         
2690                                                                                                                    
2691          Object tag = v.getTag();                                                                                  
2692          if (tag instanceof ShortcutInfo) {                                                                        
2693              onClickAppShortcut(v);                                                                                
2694          } else if (tag instanceof FolderInfo) {                                                                   
2695              if (v instanceof FolderIcon) {                                                                        
2696                  onClickFolderIcon(v);                                                                             
2697              }                                                                                                     
2698          } else if (v == mAllAppsButton) {                                                                         
2699              onClickAllAppsButton(v);                                                                              
2700          } else if (tag instanceof AppInfo) {                                                                      
2701              startAppShortcutOrInfoActivity(v);                                                                    
2702          } else if (tag instanceof LauncherAppWidgetInfo) {                                                        
2703              if (v instanceof PendingAppWidgetHostView) {                                                          
2704                  onClickPendingWidget((PendingAppWidgetHostView) v);                                               
2705              }                                                                                                     
2706          }                                                                                                         
2707      }                                                                                                             
2708                                                                                                                    
2709      public void onClickPagedViewIcon(View v) {                                                                    
2710          startAppShortcutOrInfoActivity(v);                                                                        
2711          if (mLauncherCallbacks != null) {                                                                         
2712              mLauncherCallbacks.onClickPagedViewIcon(v);                                                           
2713          }                                                                                                         
2714      }                                                                                                             
2715                                                                                                                    
2716      public boolean onTouch(View v, MotionEvent event) {                                                           
2717          return false;                                                                                             
2718      }                                                                                                             
2719                                                                                                                    
2720      /**                                                                                                           
2721       * Event handler for the app widget view which has not fully restored.                                        
2722       */                                                                                                           
2723      public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                          
2724          if (mIsSafeModeEnabled) {                                                                                 
2725              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2726              return;                                                                                               
2727          }                                                                                                         
2728                                                                                                                    
2729          final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                                    
2730          if (v.isReadyForClickSetup()) {                                                                           
2731              int widgetId = info.appWidgetId;                                                                      
2732              AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                   
2733              if (appWidgetInfo != null) {                                                                          
2734                  mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                           
2735                          this, appWidgetInfo);                                                                     
2736                  mPendingAddInfo.copyFrom(info);                                                                   
2737                  mPendingAddWidgetId = widgetId;                                                                   
2738                                                                                                                    
2739                  AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,                       
2740                          info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);                   
2741              }                                                                                                     
2742          } else if (info.installProgress < 0) {                                                                    
2743              // The install has not been queued                                                                    
2744              final String packageName = info.providerName.getPackageName();                                        
2745              showBrokenAppInstallDialog(packageName,                                                               
2746                  new DialogInterface.OnClickListener() {                                                           
2747                      public void onClick(DialogInterface dialog, int id) {                                         
2748                          startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                 
2749                      }                                                                                             
2750                  });                                                                                               
2751          } else {                                                                                                  
2752              // Download has started.                                                                              
2753              final String packageName = info.providerName.getPackageName();                                        
2754              startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                             
2755          }                                                                                                         
2756      }                                                                                                             
2757                                                                                                                    
2758      /**                                                                                                           
2759       * Event handler for the "grid" button that appears on the home screen, which                                 
2760       * enters all apps mode.                                                                                      
2761       *                                                                                                            
2762       * @param v The view that was clicked.                                                                        
2763       */                                                                                                           
2764      protected void onClickAllAppsButton(View v) {                                                                 
2765          if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                             
2766 -        if (isAllAppsVisible()) {                                                                                 
2767 +        if (isAppsViewVisible()) {                                                                                
2768              showWorkspace(true);                                                                                  
2769          } else {                                                                                                  
2770 -            showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                            
2771 -        }                                                                                                         
2772 -        if (mLauncherCallbacks != null) {                                                                         
2773 -            mLauncherCallbacks.onClickAllAppsButton(v);                                                           
2774 +            showAppsView(true /* animated */, false /* resetListToTop */);                                        
2775          }                                                                                                         
2776      }                                                                                                             
2777                                                                                                                    
2778      private void showBrokenAppInstallDialog(final String packageName,                                             
2779              DialogInterface.OnClickListener onSearchClickListener) {                                              
2780          new AlertDialog.Builder(this)                                                                             
2781              .setTitle(R.string.abandoned_promises_title)                                                          
2782              .setMessage(R.string.abandoned_promise_explanation)                                                   
2783              .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                                  
2784              .setNeutralButton(R.string.abandoned_clean_this,                                                      
2785                  new DialogInterface.OnClickListener() {                                                           
2786                      public void onClick(DialogInterface dialog, int id) {                                         
2787                          final UserHandleCompat user = UserHandleCompat.myUserHandle();                            
2788                          mWorkspace.removeAbandonedPromise(packageName, user);                                     
2789                      }                                                                                             
2790                  })                                                                                                
2791              .create().show();                                                                                     
2792          return;                                                                                                   
2793      }                                                                                                             
2794                                                                                                                    
2795      /**                                                                                                           
2796       * Event handler for an app shortcut click.                                                                   
2797       *                                                                                                            
2798       * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                          
2799       */                                                                                                           
2800      protected void onClickAppShortcut(final View v) {                                                             
2801          if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                               
2802          Object tag = v.getTag();                                                                                  
2803          if (!(tag instanceof ShortcutInfo)) {                                                                     
2804              throw new IllegalArgumentException("Input must be a Shortcut");                                       
2805          }                                                                                                         
2806                                                                                                                    
2807          // Open shortcut                                                                                          
2808          final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                         
2809                                                                                                                    
2810          if (shortcut.isDisabled != 0) {                                                                           
2811              int error = R.string.activity_not_available;                                                          
2812              if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                               
2813                  error = R.string.safemode_shortcut_error;                                                         
2814              }                                                                                                     
2815              Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                               
2816              return;                                                                                               
2817          }                                                                                                         
2818                                                                                                                    
2819          final Intent intent = shortcut.intent;                                                                    
2820                                                                                                                    
2821          // Check for special shortcuts                                                                            
2822          if (intent.getComponent() != null) {                                                                      
2823              final String shortcutClass = intent.getComponent().getClassName();                                    
2824                                                                                                                    
2825              if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                                       
2826                  MemoryDumpActivity.startDump(this);                                                               
2827                  return;                                                                                           
2828              } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                               
2829                  toggleShowWeightWatcher();                                                                        
2830                  return;                                                                                           
2831              }                                                                                                     
2832          }                                                                                                         
2833                                                                                                                    
2834          // Check for abandoned promise                                                                            
2835          if ((v instanceof BubbleTextView)                                                                         
2836                  && shortcut.isPromise()                                                                           
2837                  && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                           
2838              showBrokenAppInstallDialog(                                                                           
2839                      shortcut.getTargetComponent().getPackageName(),                                               
2840                      new DialogInterface.OnClickListener() {                                                       
2841                          public void onClick(DialogInterface dialog, int id) {                                     
2842                              startAppShortcutOrInfoActivity(v);                                                    
2843                          }                                                                                         
2844                      });                                                                                           
2845              return;                                                                                               
2846          }                                                                                                         
2847                                                                                                                    
2848          // Start activities                                                                                       
2849          startAppShortcutOrInfoActivity(v);                                                                        
2850                                                                                                                    
2851          if (mLauncherCallbacks != null) {                                                                         
2852              mLauncherCallbacks.onClickAppShortcut(v);                                                             
2853          }                                                                                                         
2854      }                                                                                                             
2855                                                                                                                    
2856 -    private void startAppShortcutOrInfoActivity(View v) {                                                         
2857 +    @Thunk void startAppShortcutOrInfoActivity(View v) {                                                          
2858          Object tag = v.getTag();                                                                                  
2859          final ShortcutInfo shortcut;                                                                              
2860          final Intent intent;                                                                                      
2861          if (tag instanceof ShortcutInfo) {                                                                        
2862              shortcut = (ShortcutInfo) tag;                                                                        
2863              intent = shortcut.intent;                                                                             
2864              int[] pos = new int[2];                                                                               
2865              v.getLocationOnScreen(pos);                                                                           
2866              intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2867                      pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2868                                                                                                                    
2869          } else if (tag instanceof AppInfo) {                                                                      
2870              shortcut = null;                                                                                      
2871              intent = ((AppInfo) tag).intent;                                                                      
2872          } else {                                                                                                  
2873              throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                            
2874          }                                                                                                         
2875                                                                                                                    
2876          boolean success = startActivitySafely(v, intent, tag);                                                    
2877          mStats.recordLaunch(intent, shortcut);                                                                    
2878                                                                                                                    
2879          if (success && v instanceof BubbleTextView) {                                                             
2880              mWaitingForResume = (BubbleTextView) v;                                                               
2881              mWaitingForResume.setStayPressed(true);                                                               
2882          }                                                                                                         
2883      }                                                                                                             
2884                                                                                                                    
2885      /**                                                                                                           
2886       * Event handler for a folder icon click.                                                                     
2887       *                                                                                                            
2888       * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                             
2889       */                                                                                                           
2890      protected void onClickFolderIcon(View v) {                                                                    
2891          if (LOGD) Log.d(TAG, "onClickFolder");                                                                    
2892          if (!(v instanceof FolderIcon)){                                                                          
2893              throw new IllegalArgumentException("Input must be a FolderIcon");                                     
2894          }                                                                                                         
2895                                                                                                                    
2896          FolderIcon folderIcon = (FolderIcon) v;                                                                   
2897          final FolderInfo info = folderIcon.getFolderInfo();                                                       
2898          Folder openFolder = mWorkspace.getFolderForTag(info);                                                     
2899                                                                                                                    
2900          // If the folder info reports that the associated folder is open, then verify that                        
2901          // it is actually opened. There have been a few instances where this gets out of sync.                    
2902          if (info.opened && openFolder == null) {                                                                  
2903              Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "                  
2904                      + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                               
2905              info.opened = false;                                                                                  
2906          }                                                                                                         
2907                                                                                                                    
2908          if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                              
2909              // Close any open folder                                                                              
2910              closeFolder();                                                                                        
2911              // Open the requested folder                                                                          
2912              openFolder(folderIcon);                                                                               
2913          } else {                                                                                                  
2914              // Find the open folder...                                                                            
2915              int folderScreen;                                                                                     
2916              if (openFolder != null) {                                                                             
2917                  folderScreen = mWorkspace.getPageForView(openFolder);                                             
2918                  // .. and close it                                                                                
2919                  closeFolder(openFolder);                                                                          
2920                  if (folderScreen != mWorkspace.getCurrentPage()) {                                                
2921                      // Close any folder open on the current screen                                                
2922                      closeFolder();                                                                                
2923                      // Pull the folder onto this screen                                                           
2924                      openFolder(folderIcon);                                                                       
2925                  }                                                                                                 
2926              }                                                                                                     
2927          }                                                                                                         
2928                                                                                                                    
2929          if (mLauncherCallbacks != null) {                                                                         
2930              mLauncherCallbacks.onClickFolderIcon(v);                                                              
2931          }                                                                                                         
2932      }                                                                                                             
2933                                                                                                                    
2934      /**                                                                                                           
2935       * Event handler for the (Add) Widgets button that appears after a long press                                 
2936       * on the home screen.                                                                                        
2937       */                                                                                                           
2938      protected void onClickAddWidgetButton(View view) {                                                            
2939          if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                           
2940          if (mIsSafeModeEnabled) {                                                                                 
2941              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2942          } else {                                                                                                  
2943 -            showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                  
2944 +            showWidgetsView(true /* animated */, true /* resetPageToZero */);                                     
2945              if (mLauncherCallbacks != null) {                                                                     
2946                  mLauncherCallbacks.onClickAddWidgetButton(view);                                                  
2947              }                                                                                                     
2948          }                                                                                                         
2949      }                                                                                                             
2950                                                                                                                    
2951      /**                                                                                                           
2952       * Event handler for the wallpaper picker button that appears after a long press                              
2953       * on the home screen.                                                                                        
2954       */                                                                                                           
2955      protected void onClickWallpaperPicker(View v) {                                                               
2956          if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                           
2957 -        final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
2958 -        pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
2959 -        startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            
2960 +        startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()),              
2961 +                REQUEST_PICK_WALLPAPER);                                                                          
2962                                                                                                                    
2963          if (mLauncherCallbacks != null) {                                                                         
2964              mLauncherCallbacks.onClickWallpaperPicker(v);                                                         
2965          }                                                                                                         
2966      }                                                                                                             
2967                                                                                                                    
2968      /**                                                                                                           
2969       * Event handler for a click on the settings button that appears after a long press                           
2970       * on the home screen.                                                                                        
2971       */                                                                                                           
2972      protected void onClickSettingsButton(View v) {                                                                
2973          if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                            
2974          if (mLauncherCallbacks != null) {                                                                         
2975              mLauncherCallbacks.onClickSettingsButton(v);                                                          
2976          }                                                                                                         
2977      }                                                                                                             
2978                                                                                                                    
2979      public void onTouchDownAllAppsButton(View v) {                                                                
2980          // Provide the same haptic feedback that the system offers for virtual keys.                              
2981          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2982      }                                                                                                             
2983                                                                                                                    
2984      public void performHapticFeedbackOnTouchDown(View v) {                                                        
2985          // Provide the same haptic feedback that the system offers for virtual keys.                              
2986          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2987      }                                                                                                             
2988                                                                                                                    
2989      public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
2990          if (mHapticFeedbackTouchListener == null) {                                                               
2991              mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           
2992                  @Override                                                                                         
2993                  public boolean onTouch(View v, MotionEvent event) {                                               
2994                      if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
2995                          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
2996                      }                                                                                             
2997                      return false;                                                                                 
2998                  }                                                                                                 
2999              };                                                                                                    
3000          }                                                                                                         
3001          return mHapticFeedbackTouchListener;                                                                      
3002      }                                                                                                             
3003                                                                                                                    
3004      public void onDragStarted(View view) {                                                                        
3005          if (isOnCustomContent()) {                                                                                
3006              // Custom content screen doesn't participate in drag and drop. If on custom                           
3007              // content screen, move to default.                                                                   
3008              moveWorkspaceToDefaultScreen();                                                                       
3009          }                                                                                                         
3010                                                                                                                    
3011          if (mLauncherCallbacks != null) {                                                                         
3012              mLauncherCallbacks.onDragStarted(view);                                                               
3013          }                                                                                                         
3014      }                                                                                                             
3015                                                                                                                    
3016      /**                                                                                                           
3017       * Called when the user stops interacting with the launcher.                                                  
3018       * This implies that the user is now on the homescreen and is not doing housekeeping.                         
3019       */                                                                                                           
3020      protected void onInteractionEnd() {                                                                           
3021          if (mLauncherCallbacks != null) {                                                                         
3022              mLauncherCallbacks.onInteractionEnd();                                                                
3023          }                                                                                                         
3024      }                                                                                                             
3025                                                                                                                    
3026      /**                                                                                                           
3027       * Called when the user starts interacting with the launcher.                                                 
3028       * The possible interactions are:                                                                             
3029       *  - open all apps                                                                                           
3030       *  - reorder an app shortcut, or a widget                                                                    
3031       *  - open the overview mode.                                                                                 
3032       * This is a good time to stop doing things that only make sense                                              
3033       * when the user is on the homescreen and not doing housekeeping.                                             
3034       */                                                                                                           
3035      protected void onInteractionBegin() {                                                                         
3036          if (mLauncherCallbacks != null) {                                                                         
3037              mLauncherCallbacks.onInteractionBegin();                                                              
3038          }                                                                                                         
3039      }                                                                                                             
3040                                                                                                                    
3041      void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {                    
3042          try {                                                                                                     
3043              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
3044              launcherApps.showAppDetailsForProfile(componentName, user);                                           
3045          } catch (SecurityException e) {                                                                           
3046              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3047              Log.e(TAG, "Launcher does not have permission to launch settings");                                   
3048          } catch (ActivityNotFoundException e) {                                                                   
3049              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3050              Log.e(TAG, "Unable to launch settings");                                                              
3051          }                                                                                                         
3052      }                                                                                                             
3053                                                                                                                    
3054      // returns true if the activity was started                                                                   
3055      boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                             
3056              UserHandleCompat user) {                                                                              
3057          if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
3058              // System applications cannot be installed. For now, show a toast explaining that.                    
3059              // We may give them the option of disabling apps this way.                                            
3060              int messageId = R.string.uninstall_system_app_text;                                                   
3061              Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
3062              return false;                                                                                         
3063          } else {                                                                                                  
3064              String packageName = componentName.getPackageName();                                                  
3065              String className = componentName.getClassName();                                                      
3066              Intent intent = new Intent(                                                                           
3067                      Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
3068              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
3069                      Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
3070              if (user != null) {                                                                                   
3071                  user.addToIntent(intent, Intent.EXTRA_USER);                                                      
3072              }                                                                                                     
3073              startActivity(intent);                                                                                
3074              return true;                                                                                          
3075          }                                                                                                         
3076      }                                                                                                             
3077                                                                                                                    
3078      boolean startActivity(View v, Intent intent, Object tag) {                                                    
3079          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
3080          try {                                                                                                     
3081              // Only launch using the new animation if the shortcut has not opted out (this is a                   
3082              // private contract between launcher and may be ignored in the future).                               
3083              boolean useLaunchAnimation = (v != null) &&                                                           
3084                      !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
3085              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
3086              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
3087                                                                                                                    
3088              UserHandleCompat user = null;                                                                         
3089              if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                         
3090                  long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                               
3091                  user = userManager.getUserForSerialNumber(serialNumber);                                          
3092              }                                                                                                     
3093                                                                                                                    
3094              Bundle optsBundle = null;                                                                             
3095              if (useLaunchAnimation) {                                                                             
3096 -                ActivityOptions opts = Utilities.isLmpOrAbove() ?                                                 
3097 -                        ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim) :       




3098 -                        ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight())🔵
3099 -                optsBundle = opts.toBundle();                                                                     
3100 +                ActivityOptions opts = null;                                                                      
3101 +                if (sClipRevealMethod != null) {                                                                  
3102 +                    // TODO: call method directly when Launcher3 can depend on M APIs                             
3103 +                    int left = 0, top = 0;                                                                        
3104 +                    int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();                             
3105 +                    if (v instanceof TextView) {                                                                  
3106 +                        // Launch from center of icon, not entire view                                            
3107 +                        Drawable icon = Workspace.getTextViewIcon((TextView) v);                                  
3108 +                        if (icon != null) {                                                                       
3109 +                            Rect bounds = icon.getBounds();                                                       
3110 +                            left = (width - bounds.width()) / 2;                                                  
3111 +                            top = v.getPaddingTop();                                                              
3112 +                            width = bounds.width();                                                               
3113 +                            height = bounds.height();                                                             
3114 +                        }                                                                                         
3115 +                    }                                                                                             
3116 +                    try {                                                                                         
3117 +                        opts = (ActivityOptions) sClipRevealMethod.invoke(null, v,                                
3118 +                                left, top, width, height);                                                        
3119 +                    } catch (IllegalAccessException e) {                                                          
3120 +                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                               
3121 +                        sClipRevealMethod = null;                                                                 
3122 +                    } catch (InvocationTargetException e) {                                                       
3123 +                        Log.d(TAG, "Could not call makeClipRevealAnimation: " + e);                               
3124 +                        sClipRevealMethod = null;                                                                 
3125 +                    }                                                                                             
3126 +                }                                                                                                 
3127 +                if (opts == null && !Utilities.isLmpOrAbove()) {                                                  
3128 +                    opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,                                          
3129 +                                    v.getMeasuredWidth(), v.getMeasuredHeight());                                 
3130 +                }                                                                                                 
3131 +                optsBundle = opts != null ? opts.toBundle() : null;                                               
3132              }                                                                                                     
3133                                                                                                                    
3134              if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                                   
3135                  // Could be launching some bookkeeping activity                                                   
3136                  startActivity(intent, optsBundle);                                                                
3137              } else {                                                                                              
3138                  // TODO Component can be null when shortcuts are supported for secondary user                     
3139                  launcherApps.startActivityForProfile(intent.getComponent(), user,                                 
3140                          intent.getSourceBounds(), optsBundle);                                                    
3141              }                                                                                                     
3142              return true;                                                                                          
3143          } catch (SecurityException e) {                                                                           
3144              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3145              Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
3146                      ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
3147                      "or use the exported attribute for this activity. "                                           
3148                      + "tag="+ tag + " intent=" + intent, e);                                                      
3149          }                                                                                                         
3150          return false;                                                                                             
3151      }                                                                                                             
3152                                                                                                                    
3153      boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
3154          boolean success = false;                                                                                  
3155          if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                         
3156              Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();                    
3157              return false;                                                                                         
3158          }                                                                                                         
3159          try {                                                                                                     
3160              success = startActivity(v, intent, tag);                                                              
3161          } catch (ActivityNotFoundException e) {                                                                   
3162              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
3163              Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
3164          }                                                                                                         
3165          return success;                                                                                           
3166      }                                                                                                             
3167                                                                                                                    
3168      /**                                                                                                           
3169       * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView                
3170       * in the DragLayer in the exact absolute location of the original FolderIcon.                                
3171       */                                                                                                           
3172      private void copyFolderIconToImage(FolderIcon fi) {                                                           
3173          final int width = fi.getMeasuredWidth();                                                                  
3174          final int height = fi.getMeasuredHeight();                                                                
3175                                                                                                                    
3176          // Lazy load ImageView, Bitmap and Canvas                                                                 
3177          if (mFolderIconImageView == null) {                                                                       
3178              mFolderIconImageView = new ImageView(this);                                                           
3179          }                                                                                                         
3180          if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                                 
3181                  mFolderIconBitmap.getHeight() != height) {                                                        
3182              mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);                      
3183              mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                                    
3184          }                                                                                                         
3185                                                                                                                    
3186          DragLayer.LayoutParams lp;                                                                                
3187          if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                           
3188              lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                                 
3189          } else {                                                                                                  
3190              lp = new DragLayer.LayoutParams(width, height);                                                       
3191          }                                                                                                         
3192                                                                                                                    
3193          // The layout from which the folder is being opened may be scaled, adjust the starting                    
3194          // view size by this scale factor.                                                                        
3195          float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);                    
3196          lp.customPosition = true;                                                                                 
3197          lp.x = mRectForFolderAnimation.left;                                                                      
3198          lp.y = mRectForFolderAnimation.top;                                                                       
3199          lp.width = (int) (scale * width);                                                                         
3200          lp.height = (int) (scale * height);                                                                       
3201                                                                                                                    
3202          mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                                    
3203          fi.draw(mFolderIconCanvas);                                                                               
3204          mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                                   
3205          if (fi.getFolder() != null) {                                                                             
3206              mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                           
3207              mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                           
3208          }                                                                                                         
3209          // Just in case this image view is still in the drag layer from a previous animation,                     
3210          // we remove it and re-add it.                                                                            
3211          if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                                
3212              mDragLayer.removeView(mFolderIconImageView);                                                          
3213          }                                                                                                         
3214          mDragLayer.addView(mFolderIconImageView, lp);                                                             
3215          if (fi.getFolder() != null) {                                                                             
3216              fi.getFolder().bringToFront();                                                                        
3217          }                                                                                                         
3218      }                                                                                                             
3219                                                                                                                    
3220      private void growAndFadeOutFolderIcon(FolderIcon fi) {                                                        
3221          if (fi == null) return;                                                                                   
3222          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                                    
3223          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                               
3224          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                               
3225                                                                                                                    
3226          FolderInfo info = (FolderInfo) fi.getTag();                                                               
3227          if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                     
3228              CellLayout cl = (CellLayout) fi.getParent().getParent();                                              
3229              CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                          
3230              cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                                      
3231          }                                                                                                         
3232                                                                                                                    
3233          // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original                      
3234          copyFolderIconToImage(fi);                                                                                
3235          fi.setVisibility(View.INVISIBLE);                                                                         
3236                                                                                                                    
3237          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3238                  scaleX, scaleY);                                                                                  
3239          if (Utilities.isLmpOrAbove()) {                                                                           
3240              oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                            
3241          }                                                                                                         
3242          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3243          oa.start();                                                                                               
3244      }                                                                                                             
3245                                                                                                                    
3246      private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                                 
3247          if (fi == null) return;                                                                                   
3248          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                                 
3249          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                               
3250          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                               
3251                                                                                                                    
3252          final CellLayout cl = (CellLayout) fi.getParent().getParent();                                            
3253                                                                                                                    
3254          // We remove and re-draw the FolderIcon in-case it has changed                                            
3255          mDragLayer.removeView(mFolderIconImageView);                                                              
3256          copyFolderIconToImage(fi);                                                                                
3257          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3258                  scaleX, scaleY);                                                                                  
3259          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3260          oa.addListener(new AnimatorListenerAdapter() {                                                            
3261              @Override                                                                                             
3262              public void onAnimationEnd(Animator animation) {                                                      
3263                  if (cl != null) {                                                                                 
3264                      cl.clearFolderLeaveBehind();                                                                  
3265                      // Remove the ImageView copy of the FolderIcon and make the original visible.                 
3266                      mDragLayer.removeView(mFolderIconImageView);                                                  
3267                      fi.setVisibility(View.VISIBLE);                                                               
3268                  }                                                                                                 
3269              }                                                                                                     
3270          });                                                                                                       
3271          oa.start();                                                                                               
3272      }                                                                                                             
3273                                                                                                                    
3274      /**                                                                                                           
3275       * Opens the user folder described by the specified tag. The opening of the folder                            
3276       * is animated relative to the specified View. If the View is null, no animation                              
3277       * is played.                                                                                                 
3278       *                                                                                                            
3279       * @param folderInfo The FolderInfo describing the folder to open.                                            
3280       */                                                                                                           
3281      public void openFolder(FolderIcon folderIcon) {                                                               
3282          Folder folder = folderIcon.getFolder();                                                                   
3283 +        Folder openFolder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                               
3284 +        if (openFolder != null && openFolder != folder) {                                                         
3285 +            // Close any open folder before opening a folder.                                                     
3286 +            closeFolder();                                                                                        
3287 +        }                                                                                                         
3288 +                                                                                                                  
3289          FolderInfo info = folder.mInfo;                                                                           
3290                                                                                                                    
3291          info.opened = true;                                                                                       
3292 +                                                                                                                  
3293 +        // While the folder is open, the position of the icon cannot change.                                      
3294 +        ((CellLayout.LayoutParams) folderIcon.getLayoutParams()).canReorder = false;                              
3295                                                                                                                    
3296          // Just verify that the folder hasn't already been added to the DragLayer.                                
3297          // There was a one-off crash where the folder had a parent already.                                       
3298          if (folder.getParent() == null) {                                                                         
3299              mDragLayer.addView(folder);                                                                           
3300              mDragController.addDropTarget((DropTarget) folder);                                                   
3301          } else {                                                                                                  
3302              Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                           
3303                      folder.getParent() + ").");                                                                   
3304          }                                                                                                         
3305          folder.animateOpen();                                                                                     
3306          growAndFadeOutFolderIcon(folderIcon);                                                                     
3307                                                                                                                    
3308          // Notify the accessibility manager that this folder "window" has appeared and occluded                   
3309          // the workspace items                                                                                    
3310          folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                              
3311          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);                    
3312      }                                                                                                             
3313                                                                                                                    
3314      public void closeFolder() {                                                                                   
3315          Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                                   
3316          if (folder != null) {                                                                                     
3317              if (folder.isEditingName()) {                                                                         
3318                  folder.dismissEditingName();                                                                      
3319              }                                                                                                     
3320              closeFolder(folder);                                                                                  
3321          }                                                                                                         
3322      }                                                                                                             
3323                                                                                                                    
3324      void closeFolder(Folder folder) {                                                                             
3325          folder.getInfo().opened = false;                                                                          
3326                                                                                                                    
3327          ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                            
3328          if (parent != null) {                                                                                     
3329              FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                                  
3330              shrinkAndFadeInFolderIcon(fi);                                                                        
3331 +            if (fi != null) {                                                                                     
3332 +                ((CellLayout.LayoutParams) fi.getLayoutParams()).canReorder = true;                               
3333 +            }                                                                                                     
3334          }                                                                                                         
3335          folder.animateClosed();                                                                                   
3336                                                                                                                    
3337          // Notify the accessibility manager that this folder "window" has disappeard and no                       
3338          // longer occludeds the workspace items                                                                   
3339          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                      
3340      }                                                                                                             
3341                                                                                                                    
3342      public boolean onLongClick(View v) {                                                                          
3343          if (!isDraggingEnabled()) return false;                                                                   
3344          if (isWorkspaceLocked()) return false;                                                                    
3345          if (mState != State.WORKSPACE) return false;                                                              
3346                                                                                                                    
3347          if (v instanceof Workspace) {                                                                             
3348              if (!mWorkspace.isInOverviewMode()) {                                                                 
3349                  if (mWorkspace.enterOverviewMode()) {                                                             
3350                      mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                          
3351                              HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                    
3352                      return true;                                                                                  
3353                  } else {                                                                                          
3354                      return false;                                                                                 
3355                  }                                                                                                 
3356              } else {                                                                                              
3357                  return false;                                                                                     
3358              }                                                                                                     
3359          }                                                                                                         
3360                                                                                                                    
3361          CellLayout.CellInfo longClickCellInfo = null;                                                             
3362          View itemUnderLongClick = null;                                                                           
3363          if (v.getTag() instanceof ItemInfo) {                                                                     
3364              ItemInfo info = (ItemInfo) v.getTag();                                                                
3365 -            longClickCellInfo = new CellLayout.CellInfo(v, info);;                                                
3366 +            longClickCellInfo = new CellLayout.CellInfo(v, info);                                                 
3367              itemUnderLongClick = longClickCellInfo.cell;                                                          
3368              resetAddInfo();                                                                                       
3369          }                                                                                                         
3370                                                                                                                    
3371          // The hotseat touch handling does not go through Workspace, and we always allow long press               
3372          // on hotseat items.                                                                                      
3373          final boolean inHotseat = isHotseatLayout(v);                                                             
3374          boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                                        
3375          if (allowLongPress && !mDragController.isDragging()) {                                                    
3376              if (itemUnderLongClick == null) {                                                                     
3377                  // User long pressed on empty space                                                               
3378                  mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                              
3379                          HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                        
3380                  if (mWorkspace.isInOverviewMode()) {                                                              
3381                      mWorkspace.startReordering(v);                                                                
3382                  } else {                                                                                          
3383                      mWorkspace.enterOverviewMode();                                                               
3384                  }                                                                                                 
3385              } else {                                                                                              
3386                  final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                                 
3387                          mHotseat.getOrderInHotseat(                                                               
3388                                  longClickCellInfo.cellX,                                                          
3389                                  longClickCellInfo.cellY));                                                        
3390                  if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                                 
3391                      // User long pressed on an item                                                               
3392                      mWorkspace.startDrag(longClickCellInfo);                                                      
3393                  }                                                                                                 
3394              }                                                                                                     
3395          }                                                                                                         
3396          return true;                                                                                              
3397      }                                                                                                             
3398                                                                                                                    
3399      boolean isHotseatLayout(View layout) {                                                                        
3400          return mHotseat != null && layout != null &&                                                              
3401                  (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                               
3402      }                                                                                                             
3403                                                                                                                    
3404      /**                                                                                                           
3405       * Returns the CellLayout of the specified container at the specified screen.                                 
3406       */                                                                                                           
3407 -    CellLayout getCellLayout(long container, long screenId) {                                                     
3408 +    public CellLayout getCellLayout(long container, long screenId) {                                              
3409          if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                          
3410              if (mHotseat != null) {                                                                               
3411                  return mHotseat.getLayout();                                                                      
3412              } else {                                                                                              
3413                  return null;                                                                                      
3414              }                                                                                                     
3415          } else {                                                                                                  
3416 -            return (CellLayout) mWorkspace.getScreenWithId(screenId);                                             
3417 -        }                                                                                                         
3418 -    }                                                                                                             
3419 -                                                                                                                  
3420 +            return mWorkspace.getScreenWithId(screenId);                                                          
3421 +        }                                                                                                         
3422 +    }                                                                                                             
3423 +                                                                                                                  
3424 +    /**                                                                                                           
3425 +     * For overridden classes.                                                                                    
3426 +     */                                                                                                           
3427      public boolean isAllAppsVisible() {                                                                           
3428 -        return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);                      
3429 +        return isAppsViewVisible();                                                                               
3430 +    }                                                                                                             
3431 +                                                                                                                  
3432 +    public boolean isAppsViewVisible() {                                                                          
3433 +        return (mState == State.APPS) || (mOnResumeState == State.APPS);                                          
3434 +    }                                                                                                             
3435 +                                                                                                                  
3436 +    public boolean isWidgetsViewVisible() {                                                                       
3437 +        return (mState == State.WIDGETS) || (mOnResumeState == State.WIDGETS);                                    
3438      }                                                                                                             
3439                                                                                                                    
3440      private void setWorkspaceBackground(boolean workspace) {                                                      
3441          mLauncherView.setBackground(workspace ?                                                                   
3442                  mWorkspaceBackgroundDrawable : null);                                                             
3443      }                                                                                                             
3444                                                                                                                    
3445      protected void changeWallpaperVisiblity(boolean visible) {                                                    
3446          int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                               
3447          int curflags = getWindow().getAttributes().flags                                                          
3448                  & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                                 
3449          if (wpflags != curflags) {                                                                                
3450              getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);                        
3451          }                                                                                                         
3452          setWorkspaceBackground(visible);                                                                          
3453 -    }                                                                                                             
3454 -                                                                                                                  
3455 -    private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {             
3456 -        if (v instanceof LauncherTransitionable) {                                                                
3457 -            ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);                
3458 -        }                                                                                                         
3459 -    }                                                                                                             
3460 -                                                                                                                  
3461 -    private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {               
3462 -        if (v instanceof LauncherTransitionable) {                                                                
3463 -            ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);                  
3464 -        }                                                                                                         
3465 -                                                                                                                  
3466 -        // Update the workspace transition step as well                                                           
3467 -        dispatchOnLauncherTransitionStep(v, 0f);                                                                  
3468 -    }                                                                                                             
3469 -                                                                                                                  
3470 -    private void dispatchOnLauncherTransitionStep(View v, float t) {                                              
3471 -        if (v instanceof LauncherTransitionable) {                                                                
3472 -            ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                                       
3473 -        }                                                                                                         
3474 -    }                                                                                                             
3475 -                                                                                                                  
3476 -    private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {                 
3477 -        if (v instanceof LauncherTransitionable) {                                                                
3478 -            ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);                    
3479 -        }                                                                                                         
3480 -                                                                                                                  
3481 -        // Update the workspace transition step as well                                                           
3482 -        dispatchOnLauncherTransitionStep(v, 1f);                                                                  
3483 -    }                                                                                                             
3484 -                                                                                                                  
3485 -    /**                                                                                                           
3486 -     * Things to test when changing the following seven functions.                                                
3487 -     *   - Home from workspace                                                                                    
3488 -     *          - from center screen                                                                              
3489 -     *          - from other screens                                                                              
3490 -     *   - Home from all apps                                                                                     
3491 -     *          - from center screen                                                                              
3492 -     *          - from other screens                                                                              
3493 -     *   - Back from all apps                                                                                     
3494 -     *          - from center screen                                                                              
3495 -     *          - from other screens                                                                              
3496 -     *   - Launch app from workspace and quit                                                                     
3497 -     *          - with back                                                                                       
3498 -     *          - with home                                                                                       
3499 -     *   - Launch app from all apps and quit                                                                      
3500 -     *          - with back                                                                                       
3501 -     *          - with home                                                                                       
3502 -     *   - Go to a screen that's not the default, then all                                                        
3503 -     *     apps, and launch and app, and go back                                                                  
3504 -     *          - with back                                                                                       
3505 -     *          -with home                                                                                        
3506 -     *   - On workspace, long press power and go back                                                             
3507 -     *          - with back                                                                                       
3508 -     *          - with home                                                                                       
3509 -     *   - On all apps, long press power and go back                                                              
3510 -     *          - with back                                                                                       
3511 -     *          - with home                                                                                       
3512 -     *   - On workspace, power off                                                                                
3513 -     *   - On all apps, power off                                                                                 
3514 -     *   - Launch an app and turn off the screen while in that app                                                
3515 -     *          - Go back with home key                                                                           
3516 -     *          - Go back with back key  TODO: make this not go to workspace                                      
3517 -     *          - From all apps                                                                                   
3518 -     *          - From workspace                                                                                  
3519 -     *   - Enter and exit car mode (becuase it causes an extra configuration changed)                             
3520 -     *          - From all apps                                                                                   
3521 -     *          - From the center workspace                                                                       
3522 -     *          - From another workspace                                                                          
3523 -     */                                                                                                           
3524 -                                                                                                                  
3525 -    /**                                                                                                           
3526 -     * Zoom the camera out from the workspace to reveal 'toView'.                                                 
3527 -     * Assumes that the view to show is anchored at either the very top or very bottom                            
3528 -     * of the screen.                                                                                             
3529 -     */                                                                                                           
3530 -    private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {                    
3531 -        AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();                  
3532 -        showAppsCustomizeHelper(animated, springLoaded, contentType);                                             
3533 -    }                                                                                                             
3534 -                                                                                                                  
3535 -    @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                                      
3536 -    private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,                      
3537 -                                         final AppsCustomizePagedView.ContentType contentType) {                  
3538 -        if (mStateAnimation != null) {                                                                            
3539 -            mStateAnimation.setDuration(0);                                                                       
3540 -            mStateAnimation.cancel();                                                                             
3541 -            mStateAnimation = null;                                                                               
3542 -        }                                                                                                         
3543 -                                                                                                                  
3544 -        boolean material = Utilities.isLmpOrAbove();                                                              
3545 -                                                                                                                  
3546 -        final Resources res = getResources();                                                                     
3547 -                                                                                                                  
3548 -        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);                      
3549 -        final int itemsAlphaStagger =                                                                             
3550 -                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3551 -                                                                                                                  
3552 -        final View fromView = mWorkspace;                                                                         
3553 -        final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                                
3554 -                                                                                                                  
3555 -        final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3556 -                                                                                                                  
3557 -        Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?              
3558 -                Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                                  
3559 -        Animator workspaceAnim =                                                                                  
3560 -                mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                         
3561 -        if (!LauncherAppState.isDisableAllApps()                                                                  
3562 -                || contentType == AppsCustomizePagedView.ContentType.Widgets) {                                   
3563 -            // Set the content type for the all apps/widgets space                                                
3564 -            mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                           
3565 -        }                                                                                                         
3566 -                                                                                                                  
3567 -        // If for some reason our views aren't initialized, don't animate                                         
3568 -        boolean initialized = getAllAppsButton() != null;                                                         
3569 -                                                                                                                  
3570 -        if (animated && initialized) {                                                                            
3571 -            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3572 -            final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3573 -                    toView.findViewById(R.id.apps_customize_pane_content);                                        
3574 -                                                                                                                  
3575 -            final View page = content.getPageAt(content.getCurrentPage());                                        
3576 -            final View revealView = toView.findViewById(R.id.fake_page);                                          
3577 -                                                                                                                  
3578 -            final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;               
3579 -            if (isWidgetTray) {                                                                                   
3580 -                revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                         
3581 -            } else {                                                                                              
3582 -                revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                              
3583 -            }                                                                                                     
3584 -                                                                                                                  
3585 -            // Hide the real page background, and swap in the fake one                                            
3586 -            content.setPageBackgroundsVisible(false);                                                             
3587 -            revealView.setVisibility(View.VISIBLE);                                                               
3588 -            // We need to hide this view as the animation start will be posted.                                   
3589 -            revealView.setAlpha(0);                                                                               
3590 -                                                                                                                  
3591 -            int width = revealView.getMeasuredWidth();                                                            
3592 -            int height = revealView.getMeasuredHeight();                                                          
3593 -            float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);                  
3594 -                                                                                                                  
3595 -            revealView.setTranslationY(0);                                                                        
3596 -            revealView.setTranslationX(0);                                                                        
3597 -                                                                                                                  
3598 -            // Get the y delta between the center of the page and the center of the all apps button               
3599 -            int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                         
3600 -                    getAllAppsButton(), null);                                                                    
3601 -                                                                                                                  
3602 -            float alpha = 0;                                                                                      
3603 -            float xDrift = 0;                                                                                     
3604 -            float yDrift = 0;                                                                                     
3605 -            if (material) {                                                                                       
3606 -                alpha = isWidgetTray ? 0.3f : 1f;                                                                 
3607 -                yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                      
3608 -                xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                               
3609 -            } else {                                                                                              
3610 -                yDrift = 2 * height / 3;                                                                          
3611 -                xDrift = 0;                                                                                       
3612 -            }                                                                                                     
3613 -            final float initAlpha = alpha;                                                                        
3614 -                                                                                                                  
3615 -            layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                      
3616 -            PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);               
3617 -            PropertyValuesHolder panelDriftY =                                                                    
3618 -                    PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                                      
3619 -            PropertyValuesHolder panelDriftX =                                                                    
3620 -                    PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                                      
3621 -                                                                                                                  
3622 -            ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,                 
3623 -                    panelAlpha, panelDriftY, panelDriftX);                                                        
3624 -                                                                                                                  
3625 -            panelAlphaAndDrift.setDuration(revealDuration);                                                       
3626 -            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                            
3627 -                                                                                                                  
3628 -            mStateAnimation.play(panelAlphaAndDrift);                                                             
3629 -                                                                                                                  
3630 -            if (page != null) {                                                                                   
3631 -                page.setVisibility(View.VISIBLE);                                                                 
3632 -                layerViews.put(page, BUILD_AND_SET_LAYER);                                                        
3633 -                                                                                                                  
3634 -                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);               
3635 -                page.setTranslationY(yDrift);                                                                     
3636 -                pageDrift.setDuration(revealDuration);                                                            
3637 -                pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                                 
3638 -                pageDrift.setStartDelay(itemsAlphaStagger);                                                       
3639 -                mStateAnimation.play(pageDrift);                                                                  
3640 -                                                                                                                  
3641 -                page.setAlpha(0f);                                                                                
3642 -                ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);                        
3643 -                itemsAlpha.setDuration(revealDuration);                                                           
3644 -                itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                                     
3645 -                itemsAlpha.setStartDelay(itemsAlphaStagger);                                                      
3646 -                mStateAnimation.play(itemsAlpha);                                                                 
3647 -            }                                                                                                     
3648 -                                                                                                                  
3649 -            View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);                        
3650 -            pageIndicators.setAlpha(0.01f);                                                                       
3651 -            ObjectAnimator indicatorsAlpha =                                                                      
3652 -                    ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                          
3653 -            indicatorsAlpha.setDuration(revealDuration);                                                          
3654 -            mStateAnimation.play(indicatorsAlpha);                                                                
3655 -                                                                                                                  
3656 -            if (material) {                                                                                       
3657 -                final View allApps = getAllAppsButton();                                                          
3658 -                int allAppsButtonSize = LauncherAppState.getInstance().                                           
3659 -                        getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                              
3660 -                float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                     
3661 -                Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,                  
3662 -                                height / 2, startRadius, revealRadius);                                           
3663 -                reveal.setDuration(revealDuration);                                                               
3664 -                reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                    
3665 -                                                                                                                  
3666 -                reveal.addListener(new AnimatorListenerAdapter() {                                                
3667 -                    public void onAnimationStart(Animator animation) {                                            
3668 -                        if (!isWidgetTray) {                                                                      
3669 -                            allApps.setVisibility(View.INVISIBLE);                                                
3670 -                        }                                                                                         
3671 -                    }                                                                                             
3672 -                    public void onAnimationEnd(Animator animation) {                                              
3673 -                        if (!isWidgetTray) {                                                                      
3674 -                            allApps.setVisibility(View.VISIBLE);                                                  
3675 -                        }                                                                                         
3676 -                    }                                                                                             
3677 -                });                                                                                               
3678 -                mStateAnimation.play(reveal);                                                                     
3679 -            }                                                                                                     
3680 -                                                                                                                  
3681 -            mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3682 -                @Override                                                                                         
3683 -                public void onAnimationEnd(Animator animation) {                                                  
3684 -                    dispatchOnLauncherTransitionEnd(fromView, animated, false);                                   
3685 -                    dispatchOnLauncherTransitionEnd(toView, animated, false);                                     
3686 -                                                                                                                  
3687 -                    revealView.setVisibility(View.INVISIBLE);                                                     
3688 -                                                                                                                  
3689 -                    for (View v : layerViews.keySet()) {                                                          
3690 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3691 -                            v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3692 -                        }                                                                                         
3693 -                    }                                                                                             
3694 -                    content.setPageBackgroundsVisible(true);                                                      
3695 -                                                                                                                  
3696 -                    // Hide the search bar                                                                        
3697 -                    if (mSearchDropTargetBar != null) {                                                           
3698 -                        mSearchDropTargetBar.hideSearchBar(false);                                                
3699 -                    }                                                                                             
3700 -                                                                                                                  
3701 -                    // This can hold unnecessary references to views.                                             
3702 -                    mStateAnimation = null;                                                                       
3703 -                }                                                                                                 
3704 -                                                                                                                  
3705 -            });                                                                                                   
3706 -                                                                                                                  
3707 -            if (workspaceAnim != null) {                                                                          
3708 -                mStateAnimation.play(workspaceAnim);                                                              
3709 -            }                                                                                                     
3710 -                                                                                                                  
3711 -            dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3712 -            dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3713 -            final AnimatorSet stateAnimation = mStateAnimation;                                                   
3714 -            final Runnable startAnimRunnable = new Runnable() {                                                   
3715 -                public void run() {                                                                               
3716 -                    // Check that mStateAnimation hasn't changed while                                            
3717 -                    // we waited for a layout/draw pass                                                           
3718 -                    if (mStateAnimation != stateAnimation)                                                        
3719 -                        return;                                                                                   
3720 -                    dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3721 -                    dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3722 -                                                                                                                  
3723 -                    revealView.setAlpha(initAlpha);                                                               
3724 -                                                                                                                  
3725 -                    for (View v : layerViews.keySet()) {                                                          
3726 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3727 -                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3728 -                        }                                                                                         
3729 -                    }                                                                                             
3730 -                                                                                                                  
3731 -                    if (Utilities.isLmpOrAbove()) {                                                               
3732 -                        for (View v : layerViews.keySet()) {                                                      
3733 -                            if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3734 -                        }                                                                                         
3735 -                    }                                                                                             
3736 -                    mStateAnimation.start();                                                                      
3737 -                }                                                                                                 
3738 -            };                                                                                                    
3739 -            toView.bringToFront();                                                                                
3740 -            toView.setVisibility(View.VISIBLE);                                                                   
3741 -            toView.post(startAnimRunnable);                                                                       
3742 -        } else {                                                                                                  
3743 -            toView.setTranslationX(0.0f);                                                                         
3744 -            toView.setTranslationY(0.0f);                                                                         
3745 -            toView.setScaleX(1.0f);                                                                               
3746 -            toView.setScaleY(1.0f);                                                                               
3747 -            toView.setVisibility(View.VISIBLE);                                                                   
3748 -            toView.bringToFront();                                                                                
3749 -                                                                                                                  
3750 -            if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                               
3751 -                // Hide the search bar                                                                            
3752 -                if (mSearchDropTargetBar != null) {                                                               
3753 -                    mSearchDropTargetBar.hideSearchBar(false);                                                    
3754 -                }                                                                                                 
3755 -            }                                                                                                     
3756 -            dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3757 -            dispatchOnLauncherTransitionStart(fromView, animated, false);                                         
3758 -            dispatchOnLauncherTransitionEnd(fromView, animated, false);                                           
3759 -            dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3760 -            dispatchOnLauncherTransitionStart(toView, animated, false);                                           
3761 -            dispatchOnLauncherTransitionEnd(toView, animated, false);                                             
3762 -        }                                                                                                         
3763 -    }                                                                                                             
3764 -                                                                                                                  
3765 -    /**                                                                                                           
3766 -     * Zoom the camera back into the workspace, hiding 'fromView'.                                                
3767 -     * This is the opposite of showAppsCustomizeHelper.                                                           
3768 -     * @param animated If true, the transition will be animated.                                                  
3769 -     */                                                                                                           
3770 -    private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                         
3771 -            final boolean springLoaded, final Runnable onCompleteRunnable) {                                      
3772 -                                                                                                                  
3773 -        if (mStateAnimation != null) {                                                                            
3774 -            mStateAnimation.setDuration(0);                                                                       
3775 -            mStateAnimation.cancel();                                                                             
3776 -            mStateAnimation = null;                                                                               
3777 -        }                                                                                                         
3778 -                                                                                                                  
3779 -        boolean material = Utilities.isLmpOrAbove();                                                              
3780 -        Resources res = getResources();                                                                           
3781 -                                                                                                                  
3782 -        final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);                     
3783 -        final int itemsAlphaStagger =                                                                             
3784 -                res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3785 -                                                                                                                  
3786 -        final View fromView = mAppsCustomizeTabHost;                                                              
3787 -        final View toView = mWorkspace;                                                                           
3788 -        Animator workspaceAnim = null;                                                                            
3789 -        final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3790 -                                                                                                                  
3791 -        if (toState == Workspace.State.NORMAL) {                                                                  
3792 -            workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3793 -                    toState, animated, layerViews);                                                               
3794 -        } else if (toState == Workspace.State.SPRING_LOADED ||                                                    
3795 -                toState == Workspace.State.OVERVIEW) {                                                            
3796 -            workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3797 -                    toState, animated, layerViews);                                                               
3798 -        }                                                                                                         
3799 -                                                                                                                  
3800 -        // If for some reason our views aren't initialized, don't animate                                         
3801 -        boolean initialized = getAllAppsButton() != null;                                                         
3802 -                                                                                                                  
3803 -        if (animated && initialized) {                                                                            
3804 -            mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3805 -            if (workspaceAnim != null) {                                                                          
3806 -                mStateAnimation.play(workspaceAnim);                                                              
3807 -            }                                                                                                     
3808 -                                                                                                                  
3809 -            final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3810 -                    fromView.findViewById(R.id.apps_customize_pane_content);                                      
3811 -                                                                                                                  
3812 -            final View page = content.getPageAt(content.getNextPage());                                           
3813 -                                                                                                                  
3814 -            // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases                 
3815 -            int count = content.getChildCount();                                                                  
3816 -            for (int i = 0; i < count; i++) {                                                                     
3817 -                View child = content.getChildAt(i);                                                               
3818 -                if (child != page) {                                                                              
3819 -                    child.setVisibility(View.INVISIBLE);                                                          
3820 -                }                                                                                                 
3821 -            }                                                                                                     
3822 -            final View revealView = fromView.findViewById(R.id.fake_page);                                        
3823 -                                                                                                                  
3824 -            // hideAppsCustomizeHelper is called in some cases when it is already hidden                          
3825 -            // don't perform all these no-op animations. In particularly, this was causing                        
3826 -            // the all-apps button to pop in and out.                                                             
3827 -            if (fromView.getVisibility() == View.VISIBLE) {                                                       
3828 -                AppsCustomizePagedView.ContentType contentType = content.getContentType();                        
3829 -                final boolean isWidgetTray =                                                                      
3830 -                        contentType == AppsCustomizePagedView.ContentType.Widgets;                                
3831 -                                                                                                                  
3832 -                if (isWidgetTray) {                                                                               
3833 -                    revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                     
3834 -                } else {                                                                                          
3835 -                    revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                          
3836 -                }                                                                                                 
3837 -                                                                                                                  
3838 -                int width = revealView.getMeasuredWidth();                                                        
3839 -                int height = revealView.getMeasuredHeight();                                                      
3840 -                float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);              
3841 -                                                                                                                  
3842 -                // Hide the real page background, and swap in the fake one                                        
3843 -                revealView.setVisibility(View.VISIBLE);                                                           
3844 -                content.setPageBackgroundsVisible(false);                                                         
3845 -                                                                                                                  
3846 -                final View allAppsButton = getAllAppsButton();                                                    
3847 -                revealView.setTranslationY(0);                                                                    
3848 -                int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                     
3849 -                        allAppsButton, null);                                                                     
3850 -                                                                                                                  
3851 -                float xDrift = 0;                                                                                 
3852 -                float yDrift = 0;                                                                                 
3853 -                if (material) {                                                                                   
3854 -                    yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                  
3855 -                    xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                           
3856 -                } else {                                                                                          
3857 -                    yDrift = 2 * height / 3;                                                                      
3858 -                    xDrift = 0;                                                                                   
3859 -                }                                                                                                 
3860 -                                                                                                                  
3861 -                layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                  
3862 -                TimeInterpolator decelerateInterpolator = material ?                                              
3863 -                        new LogDecelerateInterpolator(100, 0) :                                                   
3864 -                        new DecelerateInterpolator(1f);                                                           
3865 -                                                                                                                  
3866 -                // The vertical motion of the apps panel should be delayed by one frame                           
3867 -                // from the conceal animation in order to give the right feel. We correpsondingly                 
3868 -                // shorten the duration so that the slide and conceal end at the same time.                       
3869 -                ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",                
3870 -                        0, yDrift);                                                                               
3871 -                panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3872 -                panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3873 -                panelDriftY.setInterpolator(decelerateInterpolator);                                              
3874 -                mStateAnimation.play(panelDriftY);                                                                
3875 -                                                                                                                  
3876 -                ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",                
3877 -                        0, xDrift);                                                                               
3878 -                panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3879 -                panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3880 -                panelDriftX.setInterpolator(decelerateInterpolator);                                              
3881 -                mStateAnimation.play(panelDriftX);                                                                
3882 -                                                                                                                  
3883 -                if (isWidgetTray || !material) {                                                                  
3884 -                    float finalAlpha = material ? 0.4f : 0f;                                                      
3885 -                    revealView.setAlpha(1f);                                                                      
3886 -                    ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",                    
3887 -                            1f, finalAlpha);                                                                      
3888 -                    panelAlpha.setDuration(material ? revealDuration : 150);                                      
3889 -                    panelAlpha.setInterpolator(decelerateInterpolator);                                           
3890 -                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);              
3891 -                    mStateAnimation.play(panelAlpha);                                                             
3892 -                }                                                                                                 
3893 -                                                                                                                  
3894 -                if (page != null) {                                                                               
3895 -                    layerViews.put(page, BUILD_AND_SET_LAYER);                                                    
3896 -                                                                                                                  
3897 -                    ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",                    
3898 -                            0, yDrift);                                                                           
3899 -                    page.setTranslationY(0);                                                                      
3900 -                    pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                   
3901 -                    pageDrift.setInterpolator(decelerateInterpolator);                                            
3902 -                    pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                              
3903 -                    mStateAnimation.play(pageDrift);                                                              
3904 -                                                                                                                  
3905 -                    page.setAlpha(1f);                                                                            
3906 -                    ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);                 
3907 -                    itemsAlpha.setDuration(100);                                                                  
3908 -                    itemsAlpha.setInterpolator(decelerateInterpolator);                                           
3909 -                    mStateAnimation.play(itemsAlpha);                                                             
3910 -                }                                                                                                 
3911 -                                                                                                                  
3912 -                View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);                  
3913 -                pageIndicators.setAlpha(1f);                                                                      
3914 -                ObjectAnimator indicatorsAlpha =                                                                  
3915 -                        LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                                   
3916 -                indicatorsAlpha.setDuration(revealDuration);                                                      
3917 -                indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                                
3918 -                mStateAnimation.play(indicatorsAlpha);                                                            
3919 -                                                                                                                  
3920 -                width = revealView.getMeasuredWidth();                                                            
3921 -                                                                                                                  
3922 -                if (material) {                                                                                   
3923 -                    if (!isWidgetTray) {                                                                          
3924 -                        allAppsButton.setVisibility(View.INVISIBLE);                                              
3925 -                    }                                                                                             
3926 -                    int allAppsButtonSize = LauncherAppState.getInstance().                                       
3927 -                            getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                          
3928 -                    float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                 
3929 -                    Animator reveal =                                                                             
3930 -                            LauncherAnimUtils.createCircularReveal(revealView, width / 2,                         
3931 -                                    height / 2, revealRadius, finalRadius);                                       
3932 -                    reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                
3933 -                    reveal.setDuration(revealDuration);                                                           
3934 -                    reveal.setStartDelay(itemsAlphaStagger);                                                      
3935 -                                                                                                                  
3936 -                    reveal.addListener(new AnimatorListenerAdapter() {                                            
3937 -                        public void onAnimationEnd(Animator animation) {                                          
3938 -                            revealView.setVisibility(View.INVISIBLE);                                             
3939 -                            if (!isWidgetTray) {                                                                  
3940 -                                allAppsButton.setVisibility(View.VISIBLE);                                        
3941 -                            }                                                                                     
3942 -                        }                                                                                         
3943 -                    });                                                                                           
3944 -                                                                                                                  
3945 -                    mStateAnimation.play(reveal);                                                                 
3946 -                }                                                                                                 
3947 -                                                                                                                  
3948 -                dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                    
3949 -                dispatchOnLauncherTransitionPrepare(toView, animated, true);                                      
3950 -                mAppsCustomizeContent.stopScrolling();                                                            
3951 -            }                                                                                                     
3952 -                                                                                                                  
3953 -            mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3954 -                @Override                                                                                         
3955 -                public void onAnimationEnd(Animator animation) {                                                  
3956 -                    fromView.setVisibility(View.GONE);                                                            
3957 -                    dispatchOnLauncherTransitionEnd(fromView, animated, true);                                    
3958 -                    dispatchOnLauncherTransitionEnd(toView, animated, true);                                      
3959 -                    if (onCompleteRunnable != null) {                                                             
3960 -                        onCompleteRunnable.run();                                                                 
3961 -                    }                                                                                             
3962 -                                                                                                                  
3963 -                    for (View v : layerViews.keySet()) {                                                          
3964 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3965 -                            v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3966 -                        }                                                                                         
3967 -                    }                                                                                             
3968 -                                                                                                                  
3969 -                    content.setPageBackgroundsVisible(true);                                                      
3970 -                    // Unhide side pages                                                                          
3971 -                    int count = content.getChildCount();                                                          
3972 -                    for (int i = 0; i < count; i++) {                                                             
3973 -                        View child = content.getChildAt(i);                                                       
3974 -                        child.setVisibility(View.VISIBLE);                                                        
3975 -                    }                                                                                             
3976 -                                                                                                                  
3977 -                    // Reset page transforms                                                                      
3978 -                    if (page != null) {                                                                           
3979 -                        page.setTranslationX(0);                                                                  
3980 -                        page.setTranslationY(0);                                                                  
3981 -                        page.setAlpha(1);                                                                         
3982 -                    }                                                                                             
3983 -                    content.setCurrentPage(content.getNextPage());                                                
3984 -                                                                                                                  
3985 -                    mAppsCustomizeContent.updateCurrentPageScroll();                                              
3986 -                                                                                                                  
3987 -                    // This can hold unnecessary references to views.                                             
3988 -                    mStateAnimation = null;                                                                       
3989 -                }                                                                                                 
3990 -            });                                                                                                   
3991 -                                                                                                                  
3992 -            final AnimatorSet stateAnimation = mStateAnimation;                                                   
3993 -            final Runnable startAnimRunnable = new Runnable() {                                                   
3994 -                public void run() {                                                                               
3995 -                    // Check that mStateAnimation hasn't changed while                                            
3996 -                    // we waited for a layout/draw pass                                                           
3997 -                    if (mStateAnimation != stateAnimation)                                                        
3998 -                        return;                                                                                   
3999 -                    dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
4000 -                    dispatchOnLauncherTransitionStart(toView, animated, false);                                   
4001 -                                                                                                                  
4002 -                    for (View v : layerViews.keySet()) {                                                          
4003 -                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
4004 -                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
4005 -                        }                                                                                         
4006 -                    }                                                                                             
4007 -                                                                                                                  
4008 -                    if (Utilities.isLmpOrAbove()) {                                                               
4009 -                        for (View v : layerViews.keySet()) {                                                      
4010 -                            if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
4011 -                        }                                                                                         
4012 -                    }                                                                                             
4013 -                    mStateAnimation.start();                                                                      
4014 -                }                                                                                                 
4015 -            };                                                                                                    
4016 -            fromView.post(startAnimRunnable);                                                                     
4017 -        } else {                                                                                                  
4018 -            fromView.setVisibility(View.GONE);                                                                    
4019 -            dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
4020 -            dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
4021 -            dispatchOnLauncherTransitionEnd(fromView, animated, true);                                            
4022 -            dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
4023 -            dispatchOnLauncherTransitionStart(toView, animated, true);                                            
4024 -            dispatchOnLauncherTransitionEnd(toView, animated, true);                                              
4025 -        }                                                                                                         
4026      }                                                                                                             
4027                                                                                                                    
4028      @Override                                                                                                     
4029      public void onTrimMemory(int level) {                                                                         
4030          super.onTrimMemory(level);                                                                                
4031          if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                                 
4032              // The widget preview db can result in holding onto over                                              
4033              // 3MB of memory for caching which isn't necessary.                                                   
4034              SQLiteDatabase.releaseMemory();                                                                       
4035                                                                                                                    
4036              // This clears all widget bitmaps from the widget tray                                                
4037 -            if (mAppsCustomizeTabHost != null) {                                                                  
4038 -                mAppsCustomizeTabHost.trimMemory();                                                               
4039 -            }                                                                                                     
4040 +            // TODO(hyunyoungs)                                                                                   
4041          }                                                                                                         
4042          if (mLauncherCallbacks != null) {                                                                         
4043              mLauncherCallbacks.onTrimMemory(level);                                                               
4044          }                                                                                                         
4045      }                                                                                                             
4046                                                                                                                    
4047 +    @Override                                                                                                     
4048 +    public void onStateTransitionHideSearchBar() {                                                                
4049 +        // Hide the search bar                                                                                    
4050 +        if (mSearchDropTargetBar != null) {                                                                       
4051 +            mSearchDropTargetBar.hideSearchBar(false /* animated */);                                             
4052 +        }                                                                                                         
4053 +    }                                                                                                             
4054 +                                                                                                                  
4055      protected void showWorkspace(boolean animated) {                                                              
4056          showWorkspace(animated, null);                                                                            
4057      }                                                                                                             
4058                                                                                                                    
4059 -    protected void showWorkspace() {                                                                              
4060 -        showWorkspace(true);                                                                                      
4061 -    }                                                                                                             
4062 -                                                                                                                  
4063      void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                           
4064 -        if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {                       
4065 +        boolean changed = mState != State.WORKSPACE ||                                                            
4066 +                mWorkspace.getState() != Workspace.State.NORMAL;                                                  
4067 +        if (changed) {                                                                                            
4068              boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                          
4069              mWorkspace.setVisibility(View.VISIBLE);                                                               
4070 -            hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);                 
4071 +            mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.NORMAL,                   
4072 +                    animated, onCompleteRunnable);                                                                
4073                                                                                                                    
4074              // Show the search bar (only animate if we were showing the drop target bar in spring                 
4075              // loaded mode)                                                                                       
4076              if (mSearchDropTargetBar != null) {                                                                   
4077                  mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                            
4078              }                                                                                                     
4079                                                                                                                    
4080              // Set focus to the AppsCustomize button                                                              
4081              if (mAllAppsButton != null) {                                                                         
4082                  mAllAppsButton.requestFocus();                                                                    
4083              }                                                                                                     
4084          }                                                                                                         
4085                                                                                                                    
4086          // Change the state *after* we've called all the transition code                                          
4087          mState = State.WORKSPACE;                                                                                 
4088                                                                                                                    
4089          // Resume the auto-advance of widgets                                                                     
4090          mUserPresent = true;                                                                                      
4091 -        updateRunning();                                                                                          
4092 +        updateAutoAdvanceState();                                                                                 
4093 +                                                                                                                  
4094 +        if (changed) {                                                                                            
4095 +            // Send an accessibility event to announce the context change                                         
4096 +            getWindow().getDecorView()                                                                            
4097 +                    .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                        
4098 +                                                                                                                  
4099 +            onWorkspaceShown(animated);                                                                           
4100 +        }                                                                                                         
4101 +    }                                                                                                             
4102 +                                                                                                                  
4103 +    void showOverviewMode(boolean animated) {                                                                     
4104 +        mWorkspace.setVisibility(View.VISIBLE);                                                                   
4105 +        mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.OVERVIEW,                     
4106 +                animated, null /* onCompleteRunnable */);                                                         
4107 +        mState = State.WORKSPACE;                                                                                 
4108 +        onWorkspaceShown(animated);                                                                               
4109 +    }                                                                                                             
4110 +                                                                                                                  
4111 +    public void onWorkspaceShown(boolean animated) {                                                              
4112 +    }                                                                                                             
4113 +                                                                                                                  
4114 +    /**                                                                                                           
4115 +     * Shows the apps view.                                                                                       
4116 +     */                                                                                                           
4117 +    void showAppsView(boolean animated, boolean resetListToTop) {                                                 
4118 +        if (resetListToTop) {                                                                                     
4119 +            mAppsView.scrollToTop();                                                                              
4120 +        }                                                                                                         
4121 +        showAppsOrWidgets(animated, State.APPS);                                                                  
4122 +    }                                                                                                             
4123 +                                                                                                                  
4124 +    /**                                                                                                           
4125 +     * Shows the widgets view.                                                                                    
4126 +     */                                                                                                           
4127 +    void showWidgetsView(boolean animated, boolean resetPageToZero) {                                             
4128 +        Log.d(TAG, "showWidgetsView:" + animated + " resetPageToZero:" + resetPageToZero);                        
4129 +        if (resetPageToZero) {                                                                                    
4130 +            mWidgetsView.scrollToTop();                                                                           
4131 +        }                                                                                                         
4132 +        showAppsOrWidgets(animated, State.WIDGETS);                                                               
4133 +                                                                                                                  
4134 +        mWidgetsView.post(new Runnable() {                                                                        
4135 +            @Override                                                                                             
4136 +            public void run() {                                                                                   
4137 +                mWidgetsView.requestFocus();                                                                      
4138 +            }                                                                                                     
4139 +        });                                                                                                       
4140 +    }                                                                                                             
4141 +                                                                                                                  
4142 +    /**                                                                                                           
4143 +     * Sets up the transition to show the apps/widgets view.                                                      
4144 +     */                                                                                                           
4145 +    private void showAppsOrWidgets(boolean animated, State toState) {                                             
4146 +        if (mState != State.WORKSPACE) return;                                                                    
4147 +        if (toState != State.APPS && toState != State.WIDGETS) return;                                            
4148 +                                                                                                                  
4149 +        if (toState == State.APPS) {                                                                              
4150 +            mStateTransitionAnimation.startAnimationToAllApps(animated);                                          
4151 +            if (mLauncherCallbacks != null) {                                                                     
4152 +                mLauncherCallbacks.onAllAppsShown();                                                              
4153 +            }                                                                                                     
4154 +        } else {                                                                                                  
4155 +            mStateTransitionAnimation.startAnimationToWidgets(animated);                                          
4156 +        }                                                                                                         
4157 +                                                                                                                  
4158 +        // Change the state *after* we've called all the transition code                                          
4159 +        mState = toState;                                                                                         
4160 +                                                                                                                  
4161 +        // Pause the auto-advance of widgets until we are out of AllApps                                          
4162 +        mUserPresent = false;                                                                                     
4163 +        updateAutoAdvanceState();                                                                                 
4164 +        closeFolder();                                                                                            
4165                                                                                                                    
4166          // Send an accessibility event to announce the context change                                             
4167          getWindow().getDecorView()                                                                                
4168                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
4169 -                                                                                                                  
4170 -        onWorkspaceShown(animated);                                                                               
4171 -    }                                                                                                             
4172 -                                                                                                                  
4173 -    void showOverviewMode(boolean animated) {                                                                     
4174 -        mWorkspace.setVisibility(View.VISIBLE);                                                                   
4175 -        hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                                 
4176 -        mState = State.WORKSPACE;                                                                                 
4177 -        onWorkspaceShown(animated);                                                                               
4178 -    }                                                                                                             
4179 -                                                                                                                  
4180 -    public void onWorkspaceShown(boolean animated) {                                                              
4181 -    }                                                                                                             
4182 -                                                                                                                  
4183 -    void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                            
4184 -                     boolean resetPageToZero) {                                                                   
4185 -        if (mState != State.WORKSPACE) return;                                                                    
4186 -                                                                                                                  
4187 -        if (resetPageToZero) {                                                                                    
4188 -            mAppsCustomizeTabHost.reset();                                                                        
4189 -        }                                                                                                         
4190 -        showAppsCustomizeHelper(animated, false, contentType);                                                    
4191 -        mAppsCustomizeTabHost.post(new Runnable() {                                                               
4192 -            @Override                                                                                             
4193 -            public void run() {                                                                                   
4194 -                // We post this in-case the all apps view isn't yet constructed.                                  
4195 -                mAppsCustomizeTabHost.requestFocus();                                                             
4196 -            }                                                                                                     
4197 -        });                                                                                                       
4198 -                                                                                                                  
4199 -        // Change the state *after* we've called all the transition code                                          
4200 -        mState = State.APPS_CUSTOMIZE;                                                                            
4201 -                                                                                                                  
4202 -        // Pause the auto-advance of widgets until we are out of AllApps                                          
4203 -        mUserPresent = false;                                                                                     
4204 -        updateRunning();                                                                                          
4205 -        closeFolder();                                                                                            
4206 -                                                                                                                  
4207 -        // Send an accessibility event to announce the context change                                             
4208 -        getWindow().getDecorView()                                                                                
4209 -                .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
4210 -    }                                                                                                             
4211 -                                                                                                                  
4212 -    void enterSpringLoadedDragMode() {                                                                            
4213 -        if (isAllAppsVisible()) {                                                                                 
4214 -            hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                             
4215 -            mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                          
4216 -        }                                                                                                         
4217 -    }                                                                                                             
4218 -                                                                                                                  
4219 -    void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                                 
4220 +    }                                                                                                             
4221 +                                                                                                                  
4222 +    public void enterSpringLoadedDragMode() {                                                                     
4223 +        Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s",                                          
4224 +                mState.name()));                                                                                  
4225 +        if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||                                    
4226 +                mState == State.WIDGETS_SPRING_LOADED) {                                                          
4227 +            return;                                                                                               
4228 +        }                                                                                                         
4229 +                                                                                                                  
4230 +        mStateTransitionAnimation.startAnimationToWorkspace(mState, Workspace.State.SPRING_LOADED,                
4231 +                true /* animated */, null /* onCompleteRunnable */);                                              
4232 +        mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;                    
4233 +    }                                                                                                             
4234 +                                                                                                                  
4235 +    public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                          
4236              final Runnable onCompleteRunnable) {                                                                  
4237 -        if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                                 
4238 +        if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;                  
4239                                                                                                                    
4240          mHandler.postDelayed(new Runnable() {                                                                     
4241              @Override                                                                                             
4242              public void run() {                                                                                   
4243                  if (successfulDrop) {                                                                             
4244 +                    // TODO(hyunyoungs): verify if this hack is still needed, if not, delete.                     
4245 +                    //                                                                                            
4246                      // Before we show workspace, hide all apps again because                                      
4247                      // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should                   
4248                      // clean up our state transition functions                                                    
4249 -                    mAppsCustomizeTabHost.setVisibility(View.GONE);                                               
4250 +                    mWidgetsView.setVisibility(View.GONE);                                                        
4251                      showWorkspace(true, onCompleteRunnable);                                                      
4252                  } else {                                                                                          
4253                      exitSpringLoadedDragMode();                                                                   
4254                  }                                                                                                 
4255              }                                                                                                     
4256          }, delay);                                                                                                
4257      }                                                                                                             
4258                                                                                                                    
4259      void exitSpringLoadedDragMode() {                                                                             
4260 -        if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                                       
4261 -            final boolean animated = true;                                                                        
4262 -            final boolean springLoaded = true;                                                                    
4263 -            showAppsCustomizeHelper(animated, springLoaded);                                                      
4264 -            mState = State.APPS_CUSTOMIZE;                                                                        
4265 +        if (mState == State.APPS_SPRING_LOADED) {                                                                 
4266 +            mStateTransitionAnimation.startAnimationToAllApps(true /* animated */);                               
4267 +            mState = State.APPS;                                                                                  
4268 +        } else if (mState == State.WIDGETS_SPRING_LOADED) {                                                       
4269 +            mStateTransitionAnimation.startAnimationToWidgets(true /* animated */);                               
4270 +            mState = State.WIDGETS;                                                                               
4271          }                                                                                                         
4272          // Otherwise, we are not in spring loaded mode, so don't do anything.                                     
4273      }                                                                                                             
4274                                                                                                                    
4275      void lockAllApps() {                                                                                          
4276          // TODO                                                                                                   
4277      }                                                                                                             
4278                                                                                                                    
4279      void unlockAllApps() {                                                                                        
4280          // TODO                                                                                                   
4281      }                                                                                                             
4282                                                                                                                    
4283      protected void disableVoiceButtonProxy(boolean disable) {                                                     
4284          // NO-OP                                                                                                  
4285      }                                                                                                             
4286                                                                                                                    
4287 -    public View getQsbBar() {                                                                                     
4288 +    public View getOrCreateQsbBar() {                                                                             
4289          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
4290              return mLauncherCallbacks.getQsbBar();                                                                
4291          }                                                                                                         
4292                                                                                                                    
4293          if (mQsb == null) {                                                                                       
4294              AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);                       
4295              if (searchProvider == null) {                                                                         
4296                  return null;                                                                                      
4297              }                                                                                                     
4298                                                                                                                    
4299              Bundle opts = new Bundle();                                                                           
4300              opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                          
4301                      AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                             
4302                                                                                                                    
4303              SharedPreferences sp = getSharedPreferences(                                                          
4304                      LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                                    
4305              int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                          
4306              AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                      
4307              if (!searchProvider.provider.flattenToString().equals(                                                
4308                      sp.getString(QSB_WIDGET_PROVIDER, null))                                                      
4309                      || (widgetInfo == null)                                                                       
4310                      || !widgetInfo.provider.equals(searchProvider.provider)) {                                    
4311                  // A valid widget is not already bound.                                                           
4312                  if (widgetId > -1) {                                                                              
4313                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
4314                      widgetId = -1;                                                                                
4315                  }                                                                                                 
4316                                                                                                                    
4317                  // Try to bind a new widget                                                                       
4318                  widgetId = mAppWidgetHost.allocateAppWidgetId();                                                  
4319                                                                                                                    
4320                  if (!AppWidgetManagerCompat.getInstance(this)                                                     
4321                          .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                              
4322                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
4323                      widgetId = -1;                                                                                
4324                  }                                                                                                 
4325                                                                                                                    
4326                  sp.edit()                                                                                         
4327                      .putInt(QSB_WIDGET_ID, widgetId)                                                              
4328                      .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())                    
4329                      .commit();                                                                                    
4330              }                                                                                                     
4331                                                                                                                    
4332              if (widgetId != -1) {                                                                                 
4333                  mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                                 
4334                  mQsb.updateAppWidgetOptions(opts);                                                                
4335                  mQsb.setPadding(0, 0, 0, 0);                                                                      
4336                  mSearchDropTargetBar.addView(mQsb);                                                               
4337 +                mSearchDropTargetBar.setQsbSearchBar(mQsb);                                                       
4338              }                                                                                                     
4339          }                                                                                                         
4340          return mQsb;                                                                                              
4341 +    }                                                                                                             
4342 +                                                                                                                  
4343 +    private void reinflateQSBIfNecessary() {                                                                      
4344 +        if (mQsb instanceof LauncherAppWidgetHostView &&                                                          
4345 +                ((LauncherAppWidgetHostView) mQsb).isReinflateRequired()) {                                       
4346 +            mSearchDropTargetBar.removeView(mQsb);                                                                
4347 +            mQsb = null;                                                                                          
4348 +            mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                            
4349 +        }                                                                                                         
4350      }                                                                                                             
4351                                                                                                                    
4352      @Override                                                                                                     
4353      public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                                 
4354          final boolean result = super.dispatchPopulateAccessibilityEvent(event);                                   
4355          final List<CharSequence> text = event.getText();                                                          
4356          text.clear();                                                                                             
4357          // Populate event with a fake title based on the current state.                                           
4358 -        if (mState == State.APPS_CUSTOMIZE) {                                                                     
4359 -            text.add(mAppsCustomizeTabHost.getContentTag());                                                      
4360 +        if (mState == State.APPS) {                                                                               
4361 +            text.add("Apps");                                                                                     
4362 +        } else if (mState == State.WIDGETS) {                                                                     
4363 +            text.add("Widgets");                                                                                  
4364          } else {                                                                                                  
4365              text.add(getString(R.string.all_apps_home_button_label));                                             
4366          }                                                                                                         
4367          return result;                                                                                            
4368      }                                                                                                             
4369                                                                                                                    
4370      /**                                                                                                           
4371       * Receives notifications when system dialogs are to be closed.                                               
4372       */                                                                                                           
4373 -    private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                    
4374 +    @Thunk class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                     
4375          @Override                                                                                                 
4376          public void onReceive(Context context, Intent intent) {                                                   
4377              closeSystemDialogs();                                                                                 
4378          }                                                                                                         
4379      }                                                                                                             
4380                                                                                                                    
4381      /**                                                                                                           
4382       * Receives notifications whenever the appwidgets are reset.                                                  
4383       */                                                                                                           
4384      private class AppWidgetResetObserver extends ContentObserver {                                                
4385          public AppWidgetResetObserver() {                                                                         
4386              super(new Handler());                                                                                 
4387          }                                                                                                         
4388                                                                                                                    
4389          @Override                                                                                                 
4390          public void onChange(boolean selfChange) {                                                                
4391              onAppWidgetReset();                                                                                   
4392          }                                                                                                         
4393      }                                                                                                             
4394                                                                                                                    
4395      /**                                                                                                           
4396       * If the activity is currently paused, signal that we need to run the passed Runnable                        
4397       * in onResume.                                                                                               
4398       *                                                                                                            
4399       * This needs to be called from incoming places where resources might have been loaded                        
4400       * while we are paused.  That is becaues the Configuration might be wrong                                     
4401       * when we're not running, and if it comes back to what it was when we                                        
4402       * were paused, we are not restarted.                                                                         
4403       *                                                                                                            
4404       * Implementation of the method from LauncherModel.Callbacks.                                                 
4405       *                                                                                                            
4406       * @return true if we are currently paused.  The caller might be able to                                      
4407       * skip some work in that case since we will come back again.                                                 
4408       */                                                                                                           
4409      private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                              
4410          if (mPaused) {                                                                                            
4411              Log.i(TAG, "Deferring update until onResume");                                                        
4412              if (deletePreviousRunnables) {                                                                        
4413                  while (mBindOnResumeCallbacks.remove(run)) {                                                      
4414                  }                                                                                                 
4415              }                                                                                                     
4416              mBindOnResumeCallbacks.add(run);                                                                      
4417              return true;                                                                                          
4418          } else {                                                                                                  
4419              return false;                                                                                         
4420          }                                                                                                         
4421      }                                                                                                             
4422                                                                                                                    
4423      private boolean waitUntilResume(Runnable run) {                                                               
4424          return waitUntilResume(run, false);                                                                       
4425      }                                                                                                             
4426                                                                                                                    
4427      public void addOnResumeCallback(Runnable run) {                                                               
4428          mOnResumeCallbacks.add(run);                                                                              
4429      }                                                                                                             
4430                                                                                                                    
4431      /**                                                                                                           
4432       * If the activity is currently paused, signal that we need to re-run the loader                              
4433       * in onResume.                                                                                               
4434       *                                                                                                            
4435       * This needs to be called from incoming places where resources might have been loaded                        
4436       * while we are paused.  That is becaues the Configuration might be wrong                                     
4437       * when we're not running, and if it comes back to what it was when we                                        
4438       * were paused, we are not restarted.                                                                         
4439       *                                                                                                            
4440       * Implementation of the method from LauncherModel.Callbacks.                                                 
4441       *                                                                                                            
4442       * @return true if we are currently paused.  The caller might be able to                                      
4443       * skip some work in that case since we will come back again.                                                 
4444       */                                                                                                           
4445      public boolean setLoadOnResume() {                                                                            
4446          if (mPaused) {                                                                                            
4447              Log.i(TAG, "setLoadOnResume");                                                                        
4448              mOnResumeNeedsLoad = true;                                                                            
4449              return true;                                                                                          
4450          } else {                                                                                                  
4451              return false;                                                                                         
4452          }                                                                                                         
4453      }                                                                                                             
4454                                                                                                                    
4455      /**                                                                                                           
4456       * Implementation of the method from LauncherModel.Callbacks.                                                 
4457       */                                                                                                           
4458      public int getCurrentWorkspaceScreen() {                                                                      
4459          if (mWorkspace != null) {                                                                                 
4460              return mWorkspace.getCurrentPage();                                                                   
4461          } else {                                                                                                  
4462              return SCREEN_COUNT / 2;                                                                              
4463          }                                                                                                         
4464      }                                                                                                             
4465                                                                                                                    
4466      /**                                                                                                           
4467       * Refreshes the shortcuts shown on the workspace.                                                            
4468       *                                                                                                            
4469       * Implementation of the method from LauncherModel.Callbacks.                                                 
4470       */                                                                                                           
4471      public void startBinding() {                                                                                  
4472          setWorkspaceLoading(true);                                                                                
4473                                                                                                                    
4474          // If we're starting binding all over again, clear any bind calls we'd postponed in                       
4475          // the past (see waitUntilResume) -- we don't need them since we're starting binding                      
4476          // from scratch again                                                                                     
4477          mBindOnResumeCallbacks.clear();                                                                           
4478                                                                                                                    
4479          // Clear the workspace because it's going to be rebound                                                   
4480          mWorkspace.clearDropTargets();                                                                            
4481          mWorkspace.removeAllWorkspaceScreens();                                                                   
4482                                                                                                                    
4483          mWidgetsToAdvance.clear();                                                                                
4484          if (mHotseat != null) {                                                                                   
4485              mHotseat.resetLayout();                                                                               
4486          }                                                                                                         
4487      }                                                                                                             
4488                                                                                                                    
4489      @Override                                                                                                     
4490      public void bindScreens(ArrayList<Long> orderedScreenIds) {                                                   
4491          bindAddScreens(orderedScreenIds);                                                                         
4492                                                                                                                    
4493          // If there are no screens, we need to have an empty screen                                               
4494          if (orderedScreenIds.size() == 0) {                                                                       
4495              mWorkspace.addExtraEmptyScreen();                                                                     
4496          }                                                                                                         
4497                                                                                                                    
4498          // Create the custom content page (this call updates mDefaultScreen which calls                           
4499          // setCurrentPage() so ensure that all pages are added before calling this).                              
4500          if (hasCustomContentToLeft()) {                                                                           
4501              mWorkspace.createCustomContentContainer();                                                            
4502              populateCustomContentContainer();                                                                     
4503          }                                                                                                         
4504      }                                                                                                             
4505                                                                                                                    
4506      @Override                                                                                                     
4507      public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                                
4508          // Log to disk                                                                                            
4509          Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                            
4510          Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                              
4511                  TextUtils.join(", ", orderedScreenIds), true);                                                    
4512          int count = orderedScreenIds.size();                                                                      
4513          for (int i = 0; i < count; i++) {                                                                         
4514              mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));                        
4515          }                                                                                                         
4516      }                                                                                                             
4517                                                                                                                    
4518      @Override                                                                                                     
4519      public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                           
4520              final long screenId, final int[] cell, final int spanX, final int spanY) {                            
4521          showWorkspace(true, new Runnable() {                                                                      
4522                                                                                                                    
4523              @Override                                                                                             
4524              public void run() {                                                                                   
4525                  mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                              
4526                  addPendingItem(info, container, screenId, cell, spanX, spanY);                                    
4527              }                                                                                                     
4528          });                                                                                                       
4529      }                                                                                                             
4530                                                                                                                    
4531      private boolean shouldShowWeightWatcher() {                                                                   
4532          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4533          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4534          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                           
4535                                                                                                                    
4536          return show;                                                                                              
4537      }                                                                                                             
4538                                                                                                                    
4539      private void toggleShowWeightWatcher() {                                                                      
4540          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4541          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4542          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                                  
4543                                                                                                                    
4544          show = !show;                                                                                             
4545                                                                                                                    
4546          SharedPreferences.Editor editor = sp.edit();                                                              
4547          editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                             
4548          editor.commit();                                                                                          
4549                                                                                                                    
4550          if (mWeightWatcher != null) {                                                                             
4551              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
4552          }                                                                                                         
4553      }                                                                                                             
4554                                                                                                                    
4555      public void bindAppsAdded(final ArrayList<Long> newScreens,                                                   
4556                                final ArrayList<ItemInfo> addNotAnimated,                                           
4557                                final ArrayList<ItemInfo> addAnimated,                                              
4558                                final ArrayList<AppInfo> addedApps) {                                               
4559          Runnable r = new Runnable() {                                                                             
4560              public void run() {                                                                                   
4561                  bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                                
4562              }                                                                                                     
4563          };                                                                                                        
4564          if (waitUntilResume(r)) {                                                                                 
4565              return;                                                                                               
4566          }                                                                                                         
4567                                                                                                                    
4568          // Add the new screens                                                                                    
4569          if (newScreens != null) {                                                                                 
4570              bindAddScreens(newScreens);                                                                           
4571          }                                                                                                         
4572                                                                                                                    
4573          // We add the items without animation on non-visible pages, and with                                      
4574          // animations on the new page (which we will try and snap to).                                            
4575          if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                                
4576              bindItems(addNotAnimated, 0,                                                                          
4577                      addNotAnimated.size(), false);                                                                
4578          }                                                                                                         
4579          if (addAnimated != null && !addAnimated.isEmpty()) {                                                      
4580              bindItems(addAnimated, 0,                                                                             
4581                      addAnimated.size(), true);                                                                    
4582          }                                                                                                         
4583                                                                                                                    
4584          // Remove the extra empty screen                                                                          
4585          mWorkspace.removeExtraEmptyScreen(false, false);                                                          
4586                                                                                                                    
4587 -        if (!LauncherAppState.isDisableAllApps() &&                                                               
4588 -                addedApps != null && mAppsCustomizeContent != null) {                                             
4589 -            mAppsCustomizeContent.addApps(addedApps);                                                             
4590 +        if (addedApps != null && mAppsView != null) {                                                             
4591 +            mAppsView.addApps(addedApps);                                                                         
4592          }                                                                                                         
4593      }                                                                                                             
4594                                                                                                                    
4595      /**                                                                                                           
4596       * Bind the items start-end from the list.                                                                    
4597       *                                                                                                            
4598       * Implementation of the method from LauncherModel.Callbacks.                                                 
4599       */                                                                                                           
4600      public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,                    
4601                            final boolean forceAnimateIcons) {                                                      
4602          Runnable r = new Runnable() {                                                                             
4603              public void run() {                                                                                   
4604                  bindItems(shortcuts, start, end, forceAnimateIcons);                                              
4605              }                                                                                                     
4606          };                                                                                                        
4607          if (waitUntilResume(r)) {                                                                                 
4608              return;                                                                                               
4609          }                                                                                                         
4610                                                                                                                    
4611          // Get the list of added shortcuts and intersect them with the set of shortcuts here                      
4612          final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                           
4613          final Collection<Animator> bounceAnims = new ArrayList<Animator>();                                       
4614          final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                               
4615          Workspace workspace = mWorkspace;                                                                         
4616          long newShortcutsScreenId = -1;                                                                           
4617          for (int i = start; i < end; i++) {                                                                       
4618              final ItemInfo item = shortcuts.get(i);                                                               
4619                                                                                                                    
4620              // Short circuit if we are loading dock items for a configuration which has no dock                   
4621              if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                                 
4622                      mHotseat == null) {                                                                           
4623                  continue;                                                                                         
4624              }                                                                                                     
4625                                                                                                                    
4626              switch (item.itemType) {                                                                              
4627                  case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                            
4628                  case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                               
4629                      ShortcutInfo info = (ShortcutInfo) item;                                                      
4630                      View shortcut = createShortcut(info);                                                         
4631                                                                                                                    
4632                      /*                                                                                            
4633                       * TODO: FIX collision case                                                                   
4634                       */                                                                                           
4635                      if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                         
4636                          CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                                
4637                          if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                                
4638                              View v = cl.getChildAt(item.cellX, item.cellY);                                       
4639                              Object tag = v.getTag();                                                              
4640                              String desc = "Collision while binding workspace item: " + item                       
4641                                      + ". Collides with " + tag;                                                   
4642                              if (LauncherAppState.isDogfoodBuild()) {                                              
4643                                  throw (new RuntimeException(desc));                                               
4644                              } else {                                                                              
4645                                  Log.d(TAG, desc);                                                                 
4646                              }                                                                                     
4647                          }                                                                                         
4648                      }                                                                                             
4649                                                                                                                    
4650                      workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,            
4651                              item.cellY, 1, 1);                                                                    
4652                      if (animateIcons) {                                                                           
4653                          // Animate all the applications up now                                                    
4654                          shortcut.setAlpha(0f);                                                                    
4655                          shortcut.setScaleX(0f);                                                                   
4656                          shortcut.setScaleY(0f);                                                                   
4657                          bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                                
4658                          newShortcutsScreenId = item.screenId;                                                     
4659                      }                                                                                             
4660                      break;                                                                                        
4661                  case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                                 
4662                      FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                         
4663                              (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                         
4664                              (FolderInfo) item, mIconCache);                                                       
4665                      workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,           
4666                              item.cellY, 1, 1);                                                                    
4667                      break;                                                                                        
4668                  default:                                                                                          
4669                      throw new RuntimeException("Invalid Item Type");                                              
4670              }                                                                                                     
4671          }                                                                                                         
4672                                                                                                                    
4673          if (animateIcons) {                                                                                       
4674              // Animate to the correct page                                                                        
4675              if (newShortcutsScreenId > -1) {                                                                      
4676                  long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());              
4677                  final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);              
4678                  final Runnable startBounceAnimRunnable = new Runnable() {                                         
4679                      public void run() {                                                                           
4680                          anim.playTogether(bounceAnims);                                                           
4681                          anim.start();                                                                             
4682                      }                                                                                             
4683                  };                                                                                                
4684                  if (newShortcutsScreenId != currentScreenId) {                                                    
4685                      // We post the animation slightly delayed to prevent slowdowns                                
4686                      // when we are loading right after we return to launcher.                                     
4687                      mWorkspace.postDelayed(new Runnable() {                                                       
4688                          public void run() {                                                                       
4689                              if (mWorkspace != null) {                                                             
4690                                  mWorkspace.snapToPage(newScreenIndex);                                            
4691                                  mWorkspace.postDelayed(startBounceAnimRunnable,                                   
4692                                          NEW_APPS_ANIMATION_DELAY);                                                
4693                              }                                                                                     
4694                          }                                                                                         
4695                      }, NEW_APPS_PAGE_MOVE_DELAY);                                                                 
4696                  } else {                                                                                          
4697                      mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);                    
4698                  }                                                                                                 
4699              }                                                                                                     
4700          }                                                                                                         
4701          workspace.requestLayout();                                                                                
4702      }                                                                                                             
4703                                                                                                                    
4704      /**                                                                                                           
4705       * Implementation of the method from LauncherModel.Callbacks.                                                 
4706       */                                                                                                           
4707      public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                            
4708          Runnable r = new Runnable() {                                                                             
4709              public void run() {                                                                                   
4710                  bindFolders(folders);                                                                             
4711              }                                                                                                     
4712          };                                                                                                        
4713          if (waitUntilResume(r)) {                                                                                 
4714              return;                                                                                               
4715          }                                                                                                         
4716          sFolders.clear();                                                                                         
4717          sFolders.putAll(folders);                                                                                 
4718      }                                                                                                             
4719                                                                                                                    
4720      /**                                                                                                           
4721       * Add the views for a widget to the workspace.                                                               
4722       *                                                                                                            
4723       * Implementation of the method from LauncherModel.Callbacks.                                                 
4724       */                                                                                                           
4725      public void bindAppWidget(final LauncherAppWidgetInfo item) {                                                 
4726          Runnable r = new Runnable() {                                                                             
4727              public void run() {                                                                                   
4728                  bindAppWidget(item);                                                                              
4729              }                                                                                                     
4730          };                                                                                                        
4731          if (waitUntilResume(r)) {                                                                                 
4732              return;                                                                                               
4733          }                                                                                                         
4734                                                                                                                    
4735          final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                                        
4736          if (DEBUG_WIDGETS) {                                                                                      
4737              Log.d(TAG, "bindAppWidget: " + item);                                                                 
4738          }                                                                                                         
4739          final Workspace workspace = mWorkspace;                                                                   
4740                                                                                                                    
4741          LauncherAppWidgetProviderInfo appWidgetInfo =                                                             
4742                  LauncherModel.getProviderInfo(this, item.providerName, item.user);                                
4743                                                                                                                    
4744          if (!mIsSafeModeEnabled                                                                                   
4745                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)                    
4746                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                       
4747              if (appWidgetInfo == null) {                                                                          
4748                  if (DEBUG_WIDGETS) {                                                                              
4749                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4750                              + " belongs to component " + item.providerName                                        
4751                              + ", as the povider is null");                                                        
4752                  }                                                                                                 
4753                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4754                  return;                                                                                           
4755              }                                                                                                     
4756              // Note: This assumes that the id remap broadcast is received before this step.                       
4757              // If that is not the case, the id remap will be ignored and user may see the                         
4758              // click to setup view.                                                                               
4759              PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);                     
4760              pendingInfo.spanX = item.spanX;                                                                       
4761              pendingInfo.spanY = item.spanY;                                                                       
4762              pendingInfo.minSpanX = item.minSpanX;                                                                 
4763              pendingInfo.minSpanY = item.minSpanY;                                                                 
4764 -            Bundle options =                                                                                      
4765 -                    AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                         
4766 +            Bundle options = null;                                                                                
4767 +            //        AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                       
4768                                                                                                                    
4769              int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                               
4770              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
4771                      newWidgetId, appWidgetInfo, options);                                                         
4772                                                                                                                    
4773              // TODO consider showing a permission dialog when the widget is clicked.                              
4774              if (!success) {                                                                                       
4775                  mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                                    
4776                  if (DEBUG_WIDGETS) {                                                                              
4777                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4778                              + " belongs to component " + item.providerName                                        
4779                              + ", as the launcher is unable to bing a new widget id");                             
4780                  }                                                                                                 
4781                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4782                  return;                                                                                           
4783              }                                                                                                     
4784                                                                                                                    
4785              item.appWidgetId = newWidgetId;                                                                       
4786                                                                                                                    
4787              // If the widget has a configure activity, it is still needs to set it up, otherwise                  
4788              // the widget is ready to go.                                                                         
4789              item.restoreStatus = (appWidgetInfo.configure == null)                                                
4790                      ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                                     
4791                      : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                                    
4792                                                                                                                    
4793              LauncherModel.updateItemInDatabase(this, item);                                                       
4794          }                                                                                                         
4795                                                                                                                    
4796          if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {               
4797              final int appWidgetId = item.appWidgetId;                                                             
4798              if (DEBUG_WIDGETS) {                                                                                  
4799                  Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "                     
4800                          + appWidgetInfo.provider);                                                                
4801              }                                                                                                     
4802                                                                                                                    
4803              item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                          
4804          } else {                                                                                                  
4805              appWidgetInfo = null;                                                                                 
4806              PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                              
4807                      mIsSafeModeEnabled);                                                                          
4808              view.updateIcon(mIconCache);                                                                          
4809              item.hostView = view;                                                                                 
4810              item.hostView.updateAppWidget(null);                                                                  
4811              item.hostView.setOnClickListener(this);                                                               
4812          }                                                                                                         
4813                                                                                                                    
4814          item.hostView.setTag(item);                                                                               
4815          item.onBindAppWidget(this);                                                                               
4816                                                                                                                    
4817          workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                           
4818                  item.cellY, item.spanX, item.spanY, false);                                                       
4819          if (!item.isCustomWidget()) {                                                                             
4820              addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                         
4821          }                                                                                                         
4822                                                                                                                    
4823          workspace.requestLayout();                                                                                
4824                                                                                                                    
4825          if (DEBUG_WIDGETS) {                                                                                      
4826              Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                                 
4827                      + (SystemClock.uptimeMillis()-start) + "ms");                                                 
4828          }                                                                                                         
4829      }                                                                                                             
4830                                                                                                                    
4831      /**                                                                                                           
4832       * Restores a pending widget.                                                                                 
4833       *                                                                                                            
4834       * @param appWidgetId The app widget id                                                                       
4835       * @param cellInfo The position on screen where to create the widget.                                         
4836       */                                                                                                           
4837      private void completeRestoreAppWidget(final int appWidgetId) {                                                
4838          LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                         
4839          if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                                      
4840              Log.e(TAG, "Widget update called, when the widget no longer exists.");                                
4841              return;                                                                                               
4842          }                                                                                                         
4843                                                                                                                    
4844          LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                                       
4845          info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                             
4846                                                                                                                    
4847          mWorkspace.reinflateWidgetsIfNecessary();                                                                 
4848          LauncherModel.updateItemInDatabase(this, info);                                                           
4849      }                                                                                                             
4850                                                                                                                    
4851      public void onPageBoundSynchronously(int page) {                                                              
4852          mSynchronouslyBoundPages.add(page);                                                                       
4853      }                                                                                                             
4854                                                                                                                    
4855      /**                                                                                                           
4856       * Callback saying that there aren't any more items to bind.                                                  
4857       *                                                                                                            
4858       * Implementation of the method from LauncherModel.Callbacks.                                                 
4859       */                                                                                                           
4860 -    public void finishBindingItems(final boolean upgradePath) {                                                   
4861 +    public void finishBindingItems() {                                                                            
4862          Runnable r = new Runnable() {                                                                             
4863              public void run() {                                                                                   
4864 -                finishBindingItems(upgradePath);                                                                  
4865 +                finishBindingItems();                                                                             
4866              }                                                                                                     
4867          };                                                                                                        
4868          if (waitUntilResume(r)) {                                                                                 
4869              return;                                                                                               
4870          }                                                                                                         
4871          if (mSavedState != null) {                                                                                
4872              if (!mWorkspace.hasFocus()) {                                                                         
4873                  mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                                
4874              }                                                                                                     
4875              mSavedState = null;                                                                                   
4876          }                                                                                                         
4877                                                                                                                    
4878          mWorkspace.restoreInstanceStateForRemainingPages();                                                       
4879                                                                                                                    
4880          setWorkspaceLoading(false);                                                                               
4881          sendLoadingCompleteBroadcastIfNecessary();                                                                
4882                                                                                                                    
4883          // If we received the result of any pending adds while the loader was running (e.g. the                   
4884          // widget configuration forced an orientation change), process them now.                                  
4885          if (sPendingAddItem != null) {                                                                            
4886              final long screenId = completeAdd(sPendingAddItem);                                                   
4887                                                                                                                    
4888              // TODO: this moves the user to the page where the pending item was added. Ideally,                   
4889              // the screen would be guaranteed to exist after bind, and the page would be set through              
4890              // the workspace restore process.                                                                     
4891              mWorkspace.post(new Runnable() {                                                                      
4892                  @Override                                                                                         
4893                  public void run() {                                                                               
4894                      mWorkspace.snapToScreenId(screenId);                                                          
4895                  }                                                                                                 
4896              });                                                                                                   
4897              sPendingAddItem = null;                                                                               
4898          }                                                                                                         
4899                                                                                                                    
4900 -        if (upgradePath) {                                                                                        
4901 -            mWorkspace.getUniqueComponents(true, null);                                                           
4902 -            mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);                      
4903 -        }                                                                                                         
4904          PackageInstallerCompat.getInstance(this).onFinishBind();                                                  
4905                                                                                                                    
4906          if (mLauncherCallbacks != null) {                                                                         
4907 -            mLauncherCallbacks.finishBindingItems(upgradePath);                                                   
4908 +            mLauncherCallbacks.finishBindingItems(false);                                                         
4909          }                                                                                                         
4910      }                                                                                                             
4911                                                                                                                    
4912      private void sendLoadingCompleteBroadcastIfNecessary() {                                                      
4913          if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                               
4914              String permission =                                                                                   
4915                      getResources().getString(R.string.receive_first_load_broadcast_permission);                   
4916              Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                               
4917              sendBroadcast(intent, permission);                                                                    
4918              SharedPreferences.Editor editor = mSharedPrefs.edit();                                                
4919              editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                         
4920              editor.apply();                                                                                       
4921          }                                                                                                         
4922      }                                                                                                             
4923                                                                                                                    
4924      public boolean isAllAppsButtonRank(int rank) {                                                                
4925          if (mHotseat != null) {                                                                                   
4926              return mHotseat.isAllAppsButtonRank(rank);                                                            
4927          }                                                                                                         
4928          return false;                                                                                             
4929      }                                                                                                             
4930                                                                                                                    
4931      private boolean canRunNewAppsAnimation() {                                                                    
4932          long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                          
4933          return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                                       
4934      }                                                                                                             
4935                                                                                                                    
4936      private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                            
4937          ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                                    
4938                  PropertyValuesHolder.ofFloat("alpha", 1f),                                                        
4939                  PropertyValuesHolder.ofFloat("scaleX", 1f),                                                       
4940                  PropertyValuesHolder.ofFloat("scaleY", 1f));                                                      
4941          bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                             
4942          bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                         
4943          bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                                  
4944          return bounceAnim;                                                                                        
4945      }                                                                                                             
4946                                                                                                                    
4947      public boolean useVerticalBarLayout() {                                                                       
4948          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4949                  getDeviceProfile().isVerticalBarLayout();                                                         
4950      }                                                                                                             
4951                                                                                                                    
4952      protected Rect getSearchBarBounds() {                                                                         
4953          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4954                  getDeviceProfile().getSearchBarBounds();                                                          
4955      }                                                                                                             
4956                                                                                                                    
4957      public void bindSearchablesChanged() {                                                                        
4958          if (mSearchDropTargetBar == null) {                                                                       
4959              return;                                                                                               
4960          }                                                                                                         
4961          if (mQsb != null) {                                                                                       
4962              mSearchDropTargetBar.removeView(mQsb);                                                                
4963              mQsb = null;                                                                                          
4964          }                                                                                                         
4965 -        mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                        
4966 +        mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());                                                
4967      }                                                                                                             
4968                                                                                                                    
4969      /**                                                                                                           
4970       * Add the icons for all apps.                                                                                
4971       *                                                                                                            
4972       * Implementation of the method from LauncherModel.Callbacks.                                                 
4973       */                                                                                                           
4974      public void bindAllApplications(final ArrayList<AppInfo> apps) {                                              
4975 -        if (LauncherAppState.isDisableAllApps()) {                                                                
4976 -            if (mIntentsOnWorkspaceFromUpgradePath != null) {                                                     
4977 -                if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                                 
4978 -                    getHotseat().addAllAppsFolder(mIconCache, apps,                                               
4979 -                            mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);                       
4980 -                }                                                                                                 
4981 -                mIntentsOnWorkspaceFromUpgradePath = null;                                                        
4982 -            }                                                                                                     
4983 -            if (mAppsCustomizeContent != null) {                                                                  
4984 -                mAppsCustomizeContent.onPackagesUpdated(                                                          
4985 -                        LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
4986 -            }                                                                                                     
4987 -        } else {                                                                                                  
4988 -            if (mAppsCustomizeContent != null) {                                                                  
4989 -                mAppsCustomizeContent.setApps(apps);                                                              
4990 -                mAppsCustomizeContent.onPackagesUpdated(                                                          
4991 -                        LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
4992 -            }                                                                                                     
4993 +        if (mAppsView != null) {                                                                                  
4994 +            mAppsView.setApps(apps);                                                                              
4995 +        }                                                                                                         
4996 +        if (mWidgetsView != null) {                                                                               
4997 +            mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),                      
4998 +                    getPackageManager());                                                                         
4999          }                                                                                                         
5000          if (mLauncherCallbacks != null) {                                                                         
5001              mLauncherCallbacks.bindAllApplications(apps);                                                         
5002          }                                                                                                         
5003      }                                                                                                             
5004                                                                                                                    
5005      /**                                                                                                           
5006       * A package was updated.                                                                                     
5007       *                                                                                                            
5008       * Implementation of the method from LauncherModel.Callbacks.                                                 
5009       */                                                                                                           
5010      public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                                  
5011          Runnable r = new Runnable() {                                                                             
5012              public void run() {                                                                                   
5013                  bindAppsUpdated(apps);                                                                            
5014              }                                                                                                     
5015          };                                                                                                        
5016          if (waitUntilResume(r)) {                                                                                 
5017              return;                                                                                               
5018          }                                                                                                         
5019                                                                                                                    
5020 -        if (!LauncherAppState.isDisableAllApps() &&                                                               
5021 -                mAppsCustomizeContent != null) {                                                                  
5022 -            mAppsCustomizeContent.updateApps(apps);                                                               
5023 +        if (mAppsView != null) {                                                                                  
5024 +            mAppsView.updateApps(apps);                                                                           
5025          }                                                                                                         
5026      }                                                                                                             
5027                                                                                                                    
5028      @Override                                                                                                     
5029      public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                             
5030          Runnable r = new Runnable() {                                                                             
5031              public void run() {                                                                                   
5032                  bindWidgetsRestored(widgets);                                                                     
5033              }                                                                                                     
5034          };                                                                                                        
5035          if (waitUntilResume(r)) {                                                                                 
5036              return;                                                                                               
5037          }                                                                                                         
5038          mWorkspace.widgetsRestored(widgets);                                                                      
5039      }                                                                                                             
5040                                                                                                                    
5041      /**                                                                                                           
5042       * Some shortcuts were updated in the background.                                                             
5043       *                                                                                                            
5044       * Implementation of the method from LauncherModel.Callbacks.                                                 
5045       */                                                                                                           
5046      @Override                                                                                                     
5047      public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                                       
5048              final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                                 
5049          Runnable r = new Runnable() {                                                                             
5050              public void run() {                                                                                   
5051                  bindShortcutsChanged(updated, removed, user);                                                     
5052              }                                                                                                     
5053          };                                                                                                        
5054          if (waitUntilResume(r)) {                                                                                 
5055              return;                                                                                               
5056          }                                                                                                         
5057                                                                                                                    
5058          if (!updated.isEmpty()) {                                                                                 
5059              mWorkspace.updateShortcuts(updated);                                                                  
5060          }                                                                                                         
5061                                                                                                                    
5062          if (!removed.isEmpty()) {                                                                                 
5063              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
5064              for (ShortcutInfo si : removed) {                                                                     
5065                  removedComponents.add(si.getTargetComponent());                                                   
5066              }                                                                                                     
5067              mWorkspace.removeItemsByComponentName(removedComponents, user);                                       
5068              // Notify the drag controller                                                                         
5069              mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                            
5070          }                                                                                                         
5071      }                                                                                                             
5072                                                                                                                    
5073      /**                                                                                                           
5074       * Update the state of a package, typically related to install state.                                         
5075       *                                                                                                            
5076       * Implementation of the method from LauncherModel.Callbacks.                                                 
5077       */                                                                                                           
5078      @Override                                                                                                     
5079      public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                                   
5080          if (mWorkspace != null) {                                                                                 
5081              mWorkspace.updatePackageState(installInfo);                                                           
5082          }                                                                                                         
5083      }                                                                                                             
5084                                                                                                                    
5085      /**                                                                                                           
5086       * Update the label and icon of all the icons in a package                                                    
5087       *                                                                                                            
5088       * Implementation of the method from LauncherModel.Callbacks.                                                 
5089       */                                                                                                           
5090      @Override                                                                                                     
5091      public void updatePackageBadge(String packageName) {                                                          
5092          if (mWorkspace != null) {                                                                                 
5093              mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                          
5094          }                                                                                                         
5095      }                                                                                                             
5096                                                                                                                    
5097      /**                                                                                                           
5098       * A package was uninstalled.  We take both the super set of packageNames                                     
5099       * in addition to specific applications to remove, the reason being that                                      
5100       * this can be called when a package is updated as well.  In that scenario,                                   
5101       * we only remove specific components from the workspace, where as                                            
5102       * package-removal should clear all items by package name.                                                    
5103       *                                                                                                            
5104       * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.               
5105       * Implementation of the method from LauncherModel.Callbacks.                                                 
5106       */                                                                                                           
5107      @Override                                                                                                     
5108      public void bindComponentsRemoved(final ArrayList<String> packageNames,                                       
5109              final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {                   
5110          Runnable r = new Runnable() {                                                                             
5111              public void run() {                                                                                   
5112                  bindComponentsRemoved(packageNames, appInfos, user, reason);                                      
5113              }                                                                                                     
5114          };                                                                                                        
5115          if (waitUntilResume(r)) {                                                                                 
5116              return;                                                                                               
5117          }                                                                                                         
5118                                                                                                                    
5119          if (reason == 0) {                                                                                        
5120              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
5121              for (AppInfo info : appInfos) {                                                                       
5122                  removedComponents.add(info.componentName);                                                        
5123              }                                                                                                     
5124              if (!packageNames.isEmpty()) {                                                                        
5125                  mWorkspace.removeItemsByPackageName(packageNames, user);                                          
5126              }                                                                                                     
5127              if (!removedComponents.isEmpty()) {                                                                   
5128                  mWorkspace.removeItemsByComponentName(removedComponents, user);                                   
5129              }                                                                                                     
5130              // Notify the drag controller                                                                         
5131              mDragController.onAppsRemoved(packageNames, removedComponents);                                       
5132                                                                                                                    
5133          } else {                                                                                                  
5134              mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                                 
5135          }                                                                                                         
5136                                                                                                                    
5137          // Update AllApps                                                                                         
5138 -        if (!LauncherAppState.isDisableAllApps() &&                                                               
5139 -                mAppsCustomizeContent != null) {                                                                  
5140 -            mAppsCustomizeContent.removeApps(appInfos);                                                           
5141 +        if (mAppsView != null) {                                                                                  
5142 +            mAppsView.removeApps(appInfos);                                                                       
5143          }                                                                                                         
5144      }                                                                                                             
5145                                                                                                                    
5146      /**                                                                                                           
5147       * A number of packages were updated.                                                                         
5148       */                                                                                                           
5149 -    private ArrayList<Object> mWidgetsAndShortcuts;                                                               
5150 +    @Thunk ArrayList<Object> mWidgetsAndShortcuts;                                                                
5151      private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                              
5152              public void run() {                                                                                   
5153                  bindPackagesUpdated(mWidgetsAndShortcuts);                                                        
5154                  mWidgetsAndShortcuts = null;                                                                      
5155              }                                                                                                     
5156          };                                                                                                        
5157 +                                                                                                                  
5158      public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                                
5159          if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                                
5160              mWidgetsAndShortcuts = widgetsAndShortcuts;                                                           
5161              return;                                                                                               
5162          }                                                                                                         
5163                                                                                                                    
5164 -        // Update the widgets pane                                                                                
5165 -        if (mAppsCustomizeContent != null) {                                                                      
5166 -            mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                         
5167 +        if (mWidgetsView != null) {                                                                               
5168 +            mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),                      
5169 +                    getPackageManager());                                                                         
5170          }                                                                                                         
5171      }                                                                                                             
5172                                                                                                                    
5173      private int mapConfigurationOriActivityInfoOri(int configOri) {                                               
5174          final Display d = getWindowManager().getDefaultDisplay();                                                 
5175          int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                                     
5176          switch (d.getRotation()) {                                                                                
5177          case Surface.ROTATION_0:                                                                                  
5178          case Surface.ROTATION_180:                                                                                
5179              // We are currently in the same basic orientation as the natural orientation                          
5180              naturalOri = configOri;                                                                               
5181              break;                                                                                                
5182          case Surface.ROTATION_90:                                                                                 
5183          case Surface.ROTATION_270:                                                                                
5184              // We are currently in the other basic orientation to the natural orientation                         
5185              naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                                     
5186                      Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;                     
5187              break;                                                                                                
5188          }                                                                                                         
5189                                                                                                                    
5190          int[] oriMap = {                                                                                          
5191                  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                         
5192                  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                                        
5193                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                                 
5194                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                                 
5195          };                                                                                                        
5196          // Since the map starts at portrait, we need to offset if this device's natural orientation               
5197          // is landscape.                                                                                          
5198          int indexOffset = 0;                                                                                      
5199          if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                                  
5200              indexOffset = 1;                                                                                      
5201          }                                                                                                         
5202          return oriMap[(d.getRotation() + indexOffset) % 4];                                                       
5203      }                                                                                                             
5204                                                                                                                    
5205      public void lockScreenOrientation() {                                                                         
5206          if (Utilities.isRotationEnabled(this)) {                                                                  
5207              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                                     
5208                  setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                         
5209                          .getConfiguration().orientation));                                                        
5210              } else {                                                                                              
5211                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                                  
5212              }                                                                                                     
5213          }                                                                                                         
5214      }                                                                                                             
5215      public void unlockScreenOrientation(boolean immediate) {                                                      
5216          if (Utilities.isRotationEnabled(this)) {                                                                  
5217              if (immediate) {                                                                                      
5218                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                             
5219              } else {                                                                                              
5220                  mHandler.postDelayed(new Runnable() {                                                             
5221                      public void run() {                                                                           
5222                          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                     
5223                      }                                                                                             
5224                  }, mRestoreScreenOrientationDelay);                                                               
5225              }                                                                                                     
5226          }                                                                                                         
5227      }                                                                                                             
5228                                                                                                                    
5229      protected boolean isLauncherPreinstalled() {                                                                  
5230          if (mLauncherCallbacks != null) {                                                                         
5231              return mLauncherCallbacks.isLauncherPreinstalled();                                                   
5232          }                                                                                                         
5233          PackageManager pm = getPackageManager();                                                                  
5234          try {                                                                                                     
5235              ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);                   
5236              if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                                  
5237                  return true;                                                                                      
5238              } else {                                                                                              
5239                  return false;                                                                                     
5240              }                                                                                                     
5241          } catch (NameNotFoundException e) {                                                                       
5242              e.printStackTrace();                                                                                  
5243              return false;                                                                                         
5244          }                                                                                                         
5245      }                                                                                                             
5246                                                                                                                    
5247      /**                                                                                                           
5248       * This method indicates whether or not we should suggest default wallpaper dimensions                        
5249       * when our wallpaper cropper was not yet used to set a wallpaper.                                            
5250       */                                                                                                           
5251      protected boolean overrideWallpaperDimensions() {                                                             
5252          if (mLauncherCallbacks != null) {                                                                         
5253              return mLauncherCallbacks.overrideWallpaperDimensions();                                              
5254          }                                                                                                         
5255          return true;                                                                                              
5256      }                                                                                                             
5257                                                                                                                    
5258      /**                                                                                                           
5259       * To be overridden by subclasses to indicate that there is an activity to launch                             
5260       * before showing the standard launcher experience.                                                           
5261       */                                                                                                           
5262      protected boolean hasFirstRunActivity() {                                                                     
5263          if (mLauncherCallbacks != null) {                                                                         
5264              return mLauncherCallbacks.hasFirstRunActivity();                                                      
5265          }                                                                                                         
5266          return false;                                                                                             
5267      }                                                                                                             
5268                                                                                                                    
5269      /**                                                                                                           
5270       * To be overridden by subclasses to launch any first run activity                                            
5271       */                                                                                                           
5272      protected Intent getFirstRunActivity() {                                                                      
5273          if (mLauncherCallbacks != null) {                                                                         
5274              return mLauncherCallbacks.getFirstRunActivity();                                                      
5275          }                                                                                                         
5276          return null;                                                                                              
5277 +    }                                                                                                             
5278 +                                                                                                                  
5279 +    /**                                                                                                           
5280 +     * Returns whether the launcher callbacks overrides search in all apps.                                       
5281 +     * @return                                                                                                    
5282 +     */                                                                                                           
5283 +    @Thunk boolean isAllAppsSearchOverridden() {                                                                  
5284 +        if (mLauncherCallbacks != null) {                                                                         
5285 +            return mLauncherCallbacks.overrideAllAppsSearch();                                                    
5286 +        }                                                                                                         
5287 +        return false;                                                                                             
5288      }                                                                                                             
5289                                                                                                                    
5290      private boolean shouldRunFirstRunActivity() {                                                                 
5291          return !ActivityManager.isRunningInTestHarness() &&                                                       
5292                  !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                    
5293      }                                                                                                             
5294                                                                                                                    
5295      protected boolean hasRunFirstRunActivity() {                                                                  
5296          return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                      
5297      }                                                                                                             
5298                                                                                                                    
5299      public boolean showFirstRunActivity() {                                                                       
5300          if (shouldRunFirstRunActivity() &&                                                                        
5301                  hasFirstRunActivity()) {                                                                          
5302              Intent firstRunIntent = getFirstRunActivity();                                                        
5303              if (firstRunIntent != null) {                                                                         
5304                  startActivity(firstRunIntent);                                                                    
5305                  markFirstRunActivityShown();                                                                      
5306                  return true;                                                                                      
5307              }                                                                                                     
5308          }                                                                                                         
5309          return false;                                                                                             
5310      }                                                                                                             
5311                                                                                                                    
5312      private void markFirstRunActivityShown() {                                                                    
5313          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5314          editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                                    
5315          editor.apply();                                                                                           
5316      }                                                                                                             
5317                                                                                                                    
5318      /**                                                                                                           
5319       * To be overridden by subclasses to indicate that there is an in-activity full-screen intro                  
5320       * screen that must be displayed and dismissed.                                                               
5321       */                                                                                                           
5322      protected boolean hasDismissableIntroScreen() {                                                               
5323          if (mLauncherCallbacks != null) {                                                                         
5324              return mLauncherCallbacks.hasDismissableIntroScreen();                                                
5325          }                                                                                                         
5326          return false;                                                                                             
5327      }                                                                                                             
5328                                                                                                                    
5329      /**                                                                                                           
5330       * Full screen intro screen to be shown and dismissed before the launcher can be used.                        
5331       */                                                                                                           
5332      protected View getIntroScreen() {                                                                             
5333          if (mLauncherCallbacks != null) {                                                                         
5334              return mLauncherCallbacks.getIntroScreen();                                                           
5335          }                                                                                                         
5336          return null;                                                                                              
5337      }                                                                                                             
5338                                                                                                                    
5339      /**                                                                                                           
5340       * To be overriden by subclasses to indicate whether the in-activity intro screen has been                    
5341       * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                             
5342       */                                                                                                           
5343      private boolean shouldShowIntroScreen() {                                                                     
5344          return hasDismissableIntroScreen() &&                                                                     
5345                  !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                          
5346      }                                                                                                             
5347                                                                                                                    
5348      protected void showIntroScreen() {                                                                            
5349          View introScreen = getIntroScreen();                                                                      
5350          changeWallpaperVisiblity(false);                                                                          
5351          if (introScreen != null) {                                                                                
5352              mDragLayer.showOverlayView(introScreen);                                                              
5353          }                                                                                                         
5354          if (mLauncherOverlayContainer != null) {                                                                  
5355              mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                              
5356          }                                                                                                         
5357      }                                                                                                             
5358                                                                                                                    
5359      public void dismissIntroScreen() {                                                                            
5360          markIntroScreenDismissed();                                                                               
5361          if (showFirstRunActivity()) {                                                                             
5362              // We delay hiding the intro view until the first run activity is showing. This                       
5363              // avoids a blip.                                                                                     
5364              mWorkspace.postDelayed(new Runnable() {                                                               
5365                  @Override                                                                                         
5366                  public void run() {                                                                               
5367                      mDragLayer.dismissOverlayView();                                                              
5368                      if (mLauncherOverlayContainer != null) {                                                      
5369                          mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                    
5370                      }                                                                                             
5371                      showFirstRunClings();                                                                         
5372                  }                                                                                                 
5373              }, ACTIVITY_START_DELAY);                                                                             
5374          } else {                                                                                                  
5375              mDragLayer.dismissOverlayView();                                                                      
5376              if (mLauncherOverlayContainer != null) {                                                              
5377                  mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                            
5378              }                                                                                                     
5379              showFirstRunClings();                                                                                 
5380          }                                                                                                         
5381          changeWallpaperVisiblity(true);                                                                           
5382      }                                                                                                             
5383                                                                                                                    
5384      private void markIntroScreenDismissed() {                                                                     
5385          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5386          editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                          
5387          editor.apply();                                                                                           
5388      }                                                                                                             
5389                                                                                                                    
5390 -    private void showFirstRunClings() {                                                                           
5391 +    @Thunk void showFirstRunClings() {                                                                            
5392          // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
5393          // on the device, then we always show the first run cling experience (or if there is no                   
5394          // launcher2). Otherwise, we prompt the user upon started for migration                                   
5395          LauncherClings launcherClings = new LauncherClings(this);                                                 
5396          if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                               
5397              if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
5398                  launcherClings.showMigrationCling();                                                              
5399              } else {                                                                                              
5400                  launcherClings.showLongPressCling(true);                                                          
5401              }                                                                                                     
5402          }                                                                                                         
5403      }                                                                                                             
5404                                                                                                                    
5405      void showWorkspaceSearchAndHotseat() {                                                                        
5406          if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                          
5407          if (mHotseat != null) mHotseat.setAlpha(1f);                                                              
5408          if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                                
5409          if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                              
5410      }                                                                                                             
5411                                                                                                                    
5412      void hideWorkspaceSearchAndHotseat() {                                                                        
5413          if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                          
5414          if (mHotseat != null) mHotseat.setAlpha(0f);                                                              
5415          if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                                
5416          if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                              
5417      }                                                                                                             
5418                                                                                                                    
5419      public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                                   
5420          // Called from search suggestion, not supported in other profiles.                                        
5421          final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                          
5422          LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                                   
5423          LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,                   
5424                  myUser);                                                                                          
5425          if (activityInfo == null) {                                                                               
5426              return null;                                                                                          
5427          }                                                                                                         
5428 -        return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                         
5429 +        return new AppInfo(this, activityInfo, myUser, mIconCache);                                               
5430      }                                                                                                             
5431                                                                                                                    
5432      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5433              Bitmap icon) {                                                                                        
5434          // Called from search suggestion, not supported in other profiles.                                        
5435          return createShortcutDragInfo(shortcutIntent, caption, icon,                                              
5436                  UserHandleCompat.myUserHandle());                                                                 
5437      }                                                                                                             
5438                                                                                                                    
5439      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5440              Bitmap icon, UserHandleCompat user) {                                                                 
5441          UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                      
5442          CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);                       
5443          return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                         
5444      }                                                                                                             
5445                                                                                                                    
5446      protected void moveWorkspaceToDefaultScreen() {                                                               
5447          mWorkspace.moveToDefaultScreen(false);                                                                    
5448      }                                                                                                             
5449                                                                                                                    
5450      public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                                  
5451          dragView.setTag(dragInfo);                                                                                
5452          mWorkspace.onExternalDragStartedWithItem(dragView);                                                       
5453          mWorkspace.beginExternalDragShared(dragView, source);                                                     
5454      }                                                                                                             
5455                                                                                                                    
5456      @Override                                                                                                     
5457      public void onPageSwitch(View newPage, int newPageIndex) {                                                    
5458          if (mLauncherCallbacks != null) {                                                                         
5459              mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                               
5460          }                                                                                                         
5461      }                                                                                                             
5462                                                                                                                    
5463      /**                                                                                                           
5464       * Prints out out state for debugging.                                                                        
5465       */                                                                                                           
5466      public void dumpState() {                                                                                     
5467          Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                            
5468          Log.d(TAG, "mSavedState=" + mSavedState);                                                                 
5469          Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                                     
5470          Log.d(TAG, "mRestoring=" + mRestoring);                                                                   
5471          Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                                     
5472          Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                                 
5473          Log.d(TAG, "sFolders.size=" + sFolders.size());                                                           
5474          mModel.dumpState();                                                                                       
5475 -                                                                                                                  
5476 -        if (mAppsCustomizeContent != null) {                                                                      
5477 -            mAppsCustomizeContent.dumpState();                                                                    
5478 -        }                                                                                                         
5479 +        // TODO(hyunyoungs): add mWidgetsView.dumpState(); or mWidgetsModel.dumpState();                          
5480 +                                                                                                                  
5481          Log.d(TAG, "END launcher3 dump state");                                                                   
5482      }                                                                                                             
5483                                                                                                                    
5484      @Override                                                                                                     
5485      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {                       
5486          super.dump(prefix, fd, writer, args);                                                                     
5487          synchronized (sDumpLogs) {                                                                                
5488              writer.println(" ");                                                                                  
5489              writer.println("Debug logs: ");                                                                       
5490              for (int i = 0; i < sDumpLogs.size(); i++) {                                                          
5491                  writer.println("  " + sDumpLogs.get(i));                                                          
5492              }                                                                                                     
5493          }                                                                                                         
5494          if (mLauncherCallbacks != null) {                                                                         
5495              mLauncherCallbacks.dump(prefix, fd, writer, args);                                                    
5496          }                                                                                                         
5497      }                                                                                                             
5498                                                                                                                    
5499      public static void dumpDebugLogsToConsole() {                                                                 
5500          if (DEBUG_DUMP_LOG) {                                                                                     
5501              synchronized (sDumpLogs) {                                                                            
5502                  Log.d(TAG, "");                                                                                   
5503                  Log.d(TAG, "*********************");                                                              
5504                  Log.d(TAG, "Launcher debug logs: ");                                                              
5505                  for (int i = 0; i < sDumpLogs.size(); i++) {                                                      
5506                      Log.d(TAG, "  " + sDumpLogs.get(i));                                                          
5507                  }                                                                                                 
5508                  Log.d(TAG, "*********************");                                                              
5509                  Log.d(TAG, "");                                                                                   
5510              }                                                                                                     
5511          }                                                                                                         
5512      }                                                                                                             
5513                                                                                                                    
5514      public static void addDumpLog(String tag, String log, boolean debugLog) {                                     
5515          addDumpLog(tag, log, null, debugLog);                                                                     
5516      }                                                                                                             
5517                                                                                                                    
5518      public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {                        
5519          if (debugLog) {                                                                                           
5520              if (e != null) {                                                                                      
5521                  Log.d(tag, log, e);                                                                               
5522              } else {                                                                                              
5523                  Log.d(tag, log);                                                                                  
5524              }                                                                                                     
5525          }                                                                                                         
5526          if (DEBUG_DUMP_LOG) {                                                                                     
5527              sDateStamp.setTime(System.currentTimeMillis());                                                       
5528              synchronized (sDumpLogs) {                                                                            
5529                  sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                            
5530                      + (e == null ? "" : (", Exception: " + e)));                                                  
5531              }                                                                                                     
5532          }                                                                                                         
5533      }                                                                                                             
5534                                                                                                                    
5535      public static CustomAppWidget getCustomAppWidget(String name) {                                               
5536          return sCustomAppWidgets.get(name);                                                                       
5537      }                                                                                                             
5538                                                                                                                    
5539      public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                                        
5540          return sCustomAppWidgets;                                                                                 
5541      }                                                                                                             
5542                                                                                                                    
5543      public void dumpLogsToLocalData() {                                                                           
5544          if (DEBUG_DUMP_LOG) {                                                                                     
5545              new AsyncTask<Void, Void, Void>() {                                                                   
5546                  public Void doInBackground(Void ... args) {                                                       
5547                      boolean success = false;                                                                      
5548                      sDateStamp.setTime(sRunStart);                                                                
5549                      String FILENAME = sDateStamp.getMonth() + "-"                                                 
5550                              + sDateStamp.getDay() + "_"                                                           
5551                              + sDateStamp.getHours() + "-"                                                         
5552                              + sDateStamp.getMinutes() + "_"                                                       
5553                              + sDateStamp.getSeconds() + ".txt";                                                   
5554                                                                                                                    
5555                      FileOutputStream fos = null;                                                                  
5556                      File outFile = null;                                                                          
5557                      try {                                                                                         
5558                          outFile = new File(getFilesDir(), FILENAME);                                              
5559                          outFile.createNewFile();                                                                  
5560                          fos = new FileOutputStream(outFile);                                                      
5561                      } catch (Exception e) {                                                                       
5562                          e.printStackTrace();                                                                      
5563                      }                                                                                             
5564                      if (fos != null) {                                                                            
5565                          PrintWriter writer = new PrintWriter(fos);                                                
5566                                                                                                                    
5567                          writer.println(" ");                                                                      
5568                          writer.println("Debug logs: ");                                                           
5569                          synchronized (sDumpLogs) {                                                                
5570                              for (int i = 0; i < sDumpLogs.size(); i++) {                                          
5571                                  writer.println("  " + sDumpLogs.get(i));                                          
5572                              }                                                                                     
5573                          }                                                                                         
5574                          writer.close();                                                                           
5575                      }                                                                                             
5576                      try {                                                                                         
5577                          if (fos != null) {                                                                        
5578                              fos.close();                                                                          
5579                              success = true;                                                                       
5580                          }                                                                                         
5581                      } catch (IOException e) {                                                                     
5582                          e.printStackTrace();                                                                      
5583                      }                                                                                             
5584                      return null;                                                                                  
5585                  }                                                                                                 
5586              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
5587          }                                                                                                         
5588      }                                                                                                             
5589  }                                                                                                                 
5590                                                                                                                    
5591  interface LauncherTransitionable {                                                                                
5592      View getContent();                                                                                            
5593      void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                          
5594      void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                            
5595      void onLauncherTransitionStep(Launcher l, float t);                                                           
5596      void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                              
5597  }                                                                                                                 
5598                                                                                                                    
5599  interface DebugIntents {                                                                                          
5600      static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                         
5601      static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";                       
5602  }                                                                                                                 
   1                                                                                                                    
   2  /*                                                                                                                
   3   * Copyright (C) 2008 The Android Open Source Project                                                             
   4   *                                                                                                                
   5   * Licensed under the Apache License, Version 2.0 (the "License");                                                
   6   * you may not use this file except in compliance with the License.                                               
   7   * You may obtain a copy of the License at                                                                        
   8   *                                                                                                                
   9   *      http://www.apache.org/licenses/LICENSE-2.0                                                                
  10   *                                                                                                                
  11   * Unless required by applicable law or agreed to in writing, software                                            
  12   * distributed under the License is distributed on an "AS IS" BASIS,                                              
  13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                       
  14   * See the License for the specific language governing permissions and                                            
  15   * limitations under the License.                                                                                 
  16   */                                                                                                               
  17                                                                                                                    
  18  package com.android.launcher3;                                                                                    
  19                                                                                                                    
  20  import android.animation.Animator;                                                                                
  21  import android.animation.AnimatorListenerAdapter;                                                                 
  22  import android.animation.AnimatorSet;                                                                             
  23  import android.animation.ObjectAnimator;                                                                          
  24  import android.animation.PropertyValuesHolder;                                                                    
  25  import android.animation.TimeInterpolator;                                                                        
  26  import android.animation.ValueAnimator;                                                                           
  27  import android.annotation.TargetApi;                                                                              
  28  import android.app.Activity;                                                                                      
  29  import android.app.ActivityManager;                                                                               
  30  import android.app.ActivityOptions;                                                                               
  31  import android.app.AlertDialog;                                                                                   
  32  import android.app.SearchManager;                                                                                 
  33  import android.appwidget.AppWidgetHostView;                                                                       
  34  import android.appwidget.AppWidgetManager;                                                                        
  35  import android.appwidget.AppWidgetProviderInfo;                                                                   
  36  import android.content.ActivityNotFoundException;                                                                 
  37  import android.content.BroadcastReceiver;                                                                         
  38  import android.content.ComponentCallbacks2;                                                                       
  39  import android.content.ComponentName;                                                                             
  40  import android.content.ContentResolver;                                                                           
  41  import android.content.Context;                                                                                   
  42  import android.content.DialogInterface;                                                                           
  43  import android.content.Intent;                                                                                    
  44  import android.content.IntentFilter;                                                                              
  45  import android.content.IntentSender;                                                                              
  46  import android.content.SharedPreferences;                                                                         
  47  import android.content.pm.ActivityInfo;                                                                           
  48  import android.content.pm.ApplicationInfo;                                                                        
  49  import android.content.pm.PackageManager;                                                                         
  50  import android.content.pm.PackageManager.NameNotFoundException;                                                   
  51  import android.content.res.Configuration;                                                                         
  52  import android.content.res.Resources;                                                                             
  53  import android.database.ContentObserver;                                                                          
  54  import android.database.sqlite.SQLiteDatabase;                                                                    
  55  import android.graphics.Bitmap;                                                                                   
  56  import android.graphics.Canvas;                                                                                   
  57  import android.graphics.Color;                                                                                    
  58  import android.graphics.PorterDuff;                                                                               
  59  import android.graphics.Rect;                                                                                     
  60  import android.graphics.drawable.Drawable;                                                                        
  61  import android.net.Uri;                                                                                           
  62  import android.os.AsyncTask;                                                                                      
  63  import android.os.Build;                                                                                          
  64  import android.os.Bundle;                                                                                         
  65  import android.os.Environment;                                                                                    
  66  import android.os.Handler;                                                                                        
  67  import android.os.Message;                                                                                        
  68  import android.os.StrictMode;                                                                                     
  69  import android.os.SystemClock;                                                                                    
  70  import android.text.Selection;                                                                                    
  71  import android.text.SpannableStringBuilder;                                                                       
  72  import android.text.TextUtils;                                                                                    
  73  import android.text.method.TextKeyListener;                                                                       
  74  import android.util.Log;                                                                                          
  75  import android.view.Display;                                                                                      
  76  import android.view.Gravity;                                                                                      
  77  import android.view.HapticFeedbackConstants;                                                                      
  78  import android.view.KeyEvent;                                                                                     
  79  import android.view.LayoutInflater;                                                                               
  80  import android.view.Menu;                                                                                         
  81  import android.view.MotionEvent;                                                                                  
  82  import android.view.Surface;                                                                                      
  83  import android.view.View;                                                                                         
  84  import android.view.View.OnClickListener;                                                                         
  85  import android.view.View.OnLongClickListener;                                                                     
  86  import android.view.ViewAnimationUtils;                                                                           
  87  import android.view.ViewGroup;                                                                                    
  88  import android.view.ViewStub;                                                                                     
  89  import android.view.ViewTreeObserver;                                                                             
  90  import android.view.Window;                                                                                       
  91  import android.view.WindowManager;                                                                                
  92  import android.view.accessibility.AccessibilityEvent;                                                             
  93  import android.view.animation.AccelerateInterpolator;                                                             
  94  import android.view.animation.DecelerateInterpolator;                                                             
  95  import android.view.inputmethod.InputMethodManager;                                                               
  96  import android.widget.Advanceable;                                                                                
  97  import android.widget.FrameLayout;                                                                                
  98  import android.widget.ImageView;                                                                                  

  99  import android.widget.Toast;                                                                                      
 100                                                                                                                    
 101  import com.android.launcher3.DropTarget.DragObject;                                                               
 102  import com.android.launcher3.PagedView.PageSwitchListener;                                                        
 103  import com.android.launcher3.compat.AppWidgetManagerCompat;                                                       
 104  import com.android.launcher3.compat.LauncherActivityInfoCompat;                                                   
 105  import com.android.launcher3.compat.LauncherAppsCompat;                                                           
 106  import com.android.launcher3.compat.PackageInstallerCompat;                                                       
 107  import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;                                    
 108  import com.android.launcher3.compat.UserHandleCompat;                                                             
 109  import com.android.launcher3.compat.UserManagerCompat;                                                            



 110                                                                                                                    
 111  import java.io.DataInputStream;                                                                                   
 112  import java.io.DataOutputStream;                                                                                  
 113  import java.io.File;                                                                                              
 114  import java.io.FileDescriptor;                                                                                    
 115  import java.io.FileNotFoundException;                                                                             
 116  import java.io.FileOutputStream;                                                                                  
 117  import java.io.IOException;                                                                                       
 118  import java.io.PrintWriter;                                                                                       
 119  import java.lang.reflect.Field;                                                                                   
 120  import java.lang.reflect.InvocationTargetException;                                                               
 121  import java.lang.reflect.Method;                                                                                  
 122  import java.text.DateFormat;                                                                                      
 123  import java.util.ArrayList;                                                                                       
 124  import java.util.Collection;                                                                                      
 125  import java.util.Date;                                                                                            
 126  import java.util.HashMap;                                                                                         
 127  import java.util.HashSet;                                                                                         
 128  import java.util.List;                                                                                            
 129  import java.util.concurrent.atomic.AtomicInteger;                                                                 
 130                                                                                                                    
 131  /**                                                                                                               
 132   * Default launcher application.                                                                                  
 133   */                                                                                                               
 134  public class Launcher extends Activity                                                                            
 135          implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,                            
 136                     View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {                     


 137      static final String TAG = "Launcher";                                                                         
 138      static final boolean LOGD = false;                                                                            

 139                                                                                                                    
 140      static final boolean PROFILE_STARTUP = false;                                                                 
 141      static final boolean DEBUG_WIDGETS = false;                                                                   

 142      static final boolean DEBUG_STRICT_MODE = false;                                                               
 143      static final boolean DEBUG_RESUME_TIME = false;                                                               
 144      static final boolean DEBUG_DUMP_LOG = false;                                                                  
 145                                                                                                                    
 146      static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run                               
 147                                                                                                                    
 148      private static final int REQUEST_CREATE_SHORTCUT = 1;                                                         
 149      private static final int REQUEST_CREATE_APPWIDGET = 5;                                                        
 150      private static final int REQUEST_PICK_SHORTCUT = 7;                                                           
 151      private static final int REQUEST_PICK_APPWIDGET = 9;                                                          
 152      private static final int REQUEST_PICK_WALLPAPER = 10;                                                         
 153                                                                                                                    
 154      private static final int REQUEST_BIND_APPWIDGET = 11;                                                         
 155      private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;                                                  
 156                                                                                                                    
 157      /**                                                                                                           
 158       * IntentStarter uses request codes starting with this. This must be greater than all activity                
 159       * request codes used internally.                                                                             
 160       */                                                                                                           
 161      protected static final int REQUEST_LAST = 100;                                                                
 162                                                                                                                    
 163      static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";                                                   
 164                                                                                                                    
 165      static final int SCREEN_COUNT = 5;                                                                            
 166                                                                                                                    
 167      // To turn on these properties, type                                                                          
 168      // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]                                               
 169      static final String DUMP_STATE_PROPERTY = "launcher_dump_state";                                              
 170      static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";                                         
 171                                                                                                                    
 172      // The Intent extra that defines whether to ignore the launch animation                                       
 173      static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =                                                    
 174              "com.android.launcher3.intent.extra.shortcut.INGORE_LAUNCH_ANIMATION";                                
 175                                                                                                                    
 176      // Type: int                                                                                                  
 177      private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";                         
 178      // Type: int                                                                                                  
 179      private static final String RUNTIME_STATE = "launcher.state";                                                 
 180      // Type: int                                                                                                  
 181      private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container";                   
 182      // Type: int                                                                                                  
 183      private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";                         
 184      // Type: int                                                                                                  
 185      private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x";                         
 186      // Type: int                                                                                                  
 187      private static final String RUNTIME_STATE_PENDING_ADD_CELL_Y = "launcher.add_cell_y";                         
 188      // Type: boolean                                                                                              
 189      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME = "launcher.rename_folder";                   
 190      // Type: long                                                                                                 
 191      private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";             
 192      // Type: int                                                                                                  
 193      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_X = "launcher.add_span_x";                         
 194      // Type: int                                                                                                  
 195      private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";                         
 196      // Type: parcelable                                                                                           
 197      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";               
 198      // Type: parcelable                                                                                           
 199      private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";                   
 200      // Type: int[]                                                                                                
 201      private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";                                     
 202                                                                                                                    
 203      static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";                               
 204      static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";                   
 205                                                                                                                    
 206      static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";                                     
 207      static final String ACTION_FIRST_LOAD_COMPLETE =                                                              
 208              "com.android.launcher3.action.FIRST_LOAD_COMPLETE";                                                   
 209                                                                                                                    
 210      public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";                                            
 211      public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;                                              
 212                                                                                                                    
 213      private static final String QSB_WIDGET_ID = "qsb_widget_id";                                                  
 214      private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";                                      
 215                                                                                                                    
 216      public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";                        
 217                                                                                                                    
 218      /** The different states that Launcher can be in. */                                                          
 219      private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };                         
 220      private State mState = State.WORKSPACE;                                                                       
 221      private AnimatorSet mStateAnimation;                                                                          




 222                                                                                                                    
 223      private boolean mIsSafeModeEnabled;                                                                           
 224                                                                                                                    
 225      LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();                      
 226      LauncherOverlay mLauncherOverlay;                                                                             
 227      InsettableFrameLayout mLauncherOverlayContainer;                                                              
 228                                                                                                                    
 229      static final int APPWIDGET_HOST_ID = 1024;                                                                    
 230      public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;                                           
 231      private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;                                            
 232      private static final int ACTIVITY_START_DELAY = 1000;                                                         
 233                                                                                                                    
 234      private static final Object sLock = new Object();                                                             
 235                                                                                                                    
 236      private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();                          
 237      private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);                                   
 238                                                                                                                    
 239      // How long to wait before the new-shortcut animation automatically pans the workspace                        
 240      private static int NEW_APPS_PAGE_MOVE_DELAY = 500;                                                            
 241      private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;                                           
 242      private static int NEW_APPS_ANIMATION_DELAY = 500;                                                            
 243      private static final int SINGLE_FRAME_DELAY = 16;                                                             

 244                                                                                                                    
 245      private final BroadcastReceiver mCloseSystemDialogsReceiver                                                   
 246              = new CloseSystemDialogsIntentReceiver();                                                             
 247      private final ContentObserver mWidgetObserver = new AppWidgetResetObserver();                                 
 248                                                                                                                    
 249      private LayoutInflater mInflater;                                                                             
 250                                                                                                                    
 251      private Workspace mWorkspace;                                                                                 

 252      private View mLauncherView;                                                                                   
 253      private View mPageIndicators;                                                                                 
 254      private DragLayer mDragLayer;                                                                                 

 255      private DragController mDragController;                                                                       
 256      private View mWeightWatcher;                                                                                  
 257                                                                                                                    
 258      private AppWidgetManagerCompat mAppWidgetManager;                                                             
 259      private LauncherAppWidgetHost mAppWidgetHost;                                                                 
 260                                                                                                                    
 261      private ItemInfo mPendingAddInfo = new ItemInfo();                                                            

 262      private LauncherAppWidgetProviderInfo mPendingAddWidgetInfo;                                                  
 263      private int mPendingAddWidgetId = -1;                                                                         
 264                                                                                                                    
 265      private int[] mTmpAddItemCellCoordinates = new int[2];                                                        
 266                                                                                                                    
 267      private FolderInfo mFolderInfo;                                                                               
 268                                                                                                                    
 269      private Hotseat mHotseat;                                                                                     
 270      private ViewGroup mOverviewPanel;                                                                             
 271                                                                                                                    
 272      private View mAllAppsButton;                                                                                  
 273                                                                                                                    
 274      private SearchDropTargetBar mSearchDropTargetBar;                                                             
 275      private AppsCustomizeTabHost mAppsCustomizeTabHost;                                                           
 276      private AppsCustomizePagedView mAppsCustomizeContent;                                                         







 277      private boolean mAutoAdvanceRunning = false;                                                                  
 278      private AppWidgetHostView mQsb;                                                                               
 279                                                                                                                    
 280      private Bundle mSavedState;                                                                                   
 281      // We set the state in both onCreate and then onNewIntent in some cases, which causes both                    
 282      // scroll issues (because the workspace may not have been measured yet) and extra work.                       
 283      // Instead, just save the state that we need to restore Launcher to, and commit it in onResume.               
 284      private State mOnResumeState = State.NONE;                                                                    
 285                                                                                                                    
 286      private SpannableStringBuilder mDefaultKeySsb = null;                                                         
 287                                                                                                                    
 288      private boolean mWorkspaceLoading = true;                                                                     

 289                                                                                                                    
 290      private boolean mPaused = true;                                                                               
 291      private boolean mRestoring;                                                                                   
 292      private boolean mWaitingForResult;                                                                            
 293      private boolean mOnResumeNeedsLoad;                                                                           
 294                                                                                                                    
 295      private ArrayList<Runnable> mBindOnResumeCallbacks = new ArrayList<Runnable>();                               
 296      private ArrayList<Runnable> mOnResumeCallbacks = new ArrayList<Runnable>();                                   
 297                                                                                                                    
 298      private Bundle mSavedInstanceState;                                                                           
 299                                                                                                                    
 300      private LauncherModel mModel;                                                                                 
 301      private IconCache mIconCache;                                                                                 
 302      private boolean mUserPresent = true;                                                                          

 303      private boolean mVisible = false;                                                                             
 304      private boolean mHasFocus = false;                                                                            
 305      private boolean mAttached = false;                                                                            
 306                                                                                                                    
 307      private static LocaleConfiguration sLocaleConfiguration = null;                                               

 308                                                                                                                    
 309      private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>();                          
 310                                                                                                                    
 311      private View.OnTouchListener mHapticFeedbackTouchListener;                                                    
 312                                                                                                                    
 313      public static final int BUILD_LAYER = 0;                                                                      
 314      public static final int BUILD_AND_SET_LAYER = 1;                                                              
 315                                                                                                                    
 316      // Related to the auto-advancing of widgets                                                                   
 317      private final int ADVANCE_MSG = 1;                                                                            
 318      private final int mAdvanceInterval = 20000;                                                                   
 319      private final int mAdvanceStagger = 250;                                                                      
 320      private long mAutoAdvanceSentTime;                                                                            
 321      private long mAutoAdvanceTimeLeft = -1;                                                                       
 322      private HashMap<View, AppWidgetProviderInfo> mWidgetsToAdvance =                                              

 323          new HashMap<View, AppWidgetProviderInfo>();                                                               
 324                                                                                                                    
 325      // Determines how long to wait after a rotation before restoring the screen orientation to                    
 326      // match the sensor state.                                                                                    
 327      private final int mRestoreScreenOrientationDelay = 500;                                                       
 328                                                                                                                    
 329      private Drawable mWorkspaceBackgroundDrawable;                                                                

 330                                                                                                                    
 331      private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();                         
 332      private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;                                
 333                                                                                                                    
 334      static final ArrayList<String> sDumpLogs = new ArrayList<String>();                                           
 335      static Date sDateStamp = new Date();                                                                          
 336      static DateFormat sDateFormat =                                                                               
 337              DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);                                   
 338      static long sRunStart = System.currentTimeMillis();                                                           
 339      static final String CORRUPTION_EMAIL_SENT_KEY = "corruptionEmailSent";                                        
 340                                                                                                                    
 341      // We only want to get the SharedPreferences once since it does an FS stat each time we get                   
 342      // it from the context.                                                                                       
 343      private SharedPreferences mSharedPrefs;                                                                       
 344                                                                                                                    
 345      private static ArrayList<ComponentName> mIntentsOnWorkspaceFromUpgradePath = null;                            
 346                                                                                                                    
 347      // Holds the page that we need to animate to, and the icon views that we need to animate up                   
 348      // when we scroll to that page on resume.                                                                     
 349      private ImageView mFolderIconImageView;                                                                       

 350      private Bitmap mFolderIconBitmap;                                                                             
 351      private Canvas mFolderIconCanvas;                                                                             
 352      private Rect mRectForFolderAnimation = new Rect();                                                            
 353                                                                                                                    
 354      private BubbleTextView mWaitingForResume;                                                                     
 355                                                                                                                    
 356      protected static HashMap<String, CustomAppWidget> sCustomAppWidgets =                                         
 357              new HashMap<String, CustomAppWidget>();                                                               
 358                                                                                                                    
 359      private static final boolean ENABLE_CUSTOM_WIDGET_TEST = false;                                               
 360      static {                                                                                                      
 361          if (ENABLE_CUSTOM_WIDGET_TEST) {                                                                          
 362              sCustomAppWidgets.put(DummyWidget.class.getName(), new DummyWidget());                                
 363          }                                                                                                         
 364      }                                                                                                             
 365                                                                                                                    
 366      private Runnable mBuildLayersRunnable = new Runnable() {                                                      













 367          public void run() {                                                                                       
 368              if (mWorkspace != null) {                                                                             
 369                  mWorkspace.buildPageHardwareLayers();                                                             
 370              }                                                                                                     
 371          }                                                                                                         
 372      };                                                                                                            
 373                                                                                                                    
 374      private static PendingAddArguments sPendingAddItem;                                                           
 375                                                                                                                    
 376      private static class PendingAddArguments {                                                                    

 377          int requestCode;                                                                                          
 378          Intent intent;                                                                                            
 379          long container;                                                                                           
 380          long screenId;                                                                                            
 381          int cellX;                                                                                                
 382          int cellY;                                                                                                
 383          int appWidgetId;                                                                                          
 384      }                                                                                                             
 385                                                                                                                    
 386      private Stats mStats;                                                                                         
 387                                                                                                                    
 388      FocusIndicatorView mFocusHandler;                                                                             
 389                                                                                                                    
 390      @Override                                                                                                     
 391      protected void onCreate(Bundle savedInstanceState) {                                                          
 392          if (DEBUG_STRICT_MODE) {                                                                                  
 393              StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                                      
 394                      .detectDiskReads()                                                                            
 395                      .detectDiskWrites()                                                                           
 396                      .detectNetwork()   // or .detectAll() for all detectable problems                             
 397                      .penaltyLog()                                                                                 
 398                      .build());                                                                                    
 399              StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                                              
 400                      .detectLeakedSqlLiteObjects()                                                                 
 401                      .detectLeakedClosableObjects()                                                                
 402                      .penaltyLog()                                                                                 
 403                      .penaltyDeath()                                                                               
 404                      .build());                                                                                    
 405          }                                                                                                         
 406                                                                                                                    
 407          if (mLauncherCallbacks != null) {                                                                         
 408              mLauncherCallbacks.preOnCreate();                                                                     
 409          }                                                                                                         
 410                                                                                                                    
 411          super.onCreate(savedInstanceState);                                                                       
 412                                                                                                                    
 413          LauncherAppState.setApplicationContext(getApplicationContext());                                          
 414          LauncherAppState app = LauncherAppState.getInstance();                                                    
 415          LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);                           
 416                                                                                                                    
 417          // Lazy-initialize the dynamic grid                                                                       
 418          DeviceProfile grid = app.initDynamicGrid(this);                                                           
 419                                                                                                                    
 420          // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet   
 421          mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),                           
 422                  Context.MODE_PRIVATE);                                                                            
 423          mIsSafeModeEnabled = getPackageManager().isSafeMode();                                                    
 424          mModel = app.setLauncher(this);                                                                           
 425          mIconCache = app.getIconCache();                                                                          
 426          mIconCache.flushInvalidIcons(grid);                                                                       
 427          mDragController = new DragController(this);                                                               
 428          mInflater = getLayoutInflater();                                                                          

 429                                                                                                                    
 430          mStats = new Stats(this);                                                                                 
 431                                                                                                                    
 432          mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);                                             
 433                                                                                                                    
 434          mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);                                      
 435          mAppWidgetHost.startListening();                                                                          
 436                                                                                                                    
 437          // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,                
 438          // this also ensures that any synchronous binding below doesn't re-trigger another                        
 439          // LauncherModel load.                                                                                    
 440          mPaused = false;                                                                                          
 441                                                                                                                    
 442          if (PROFILE_STARTUP) {                                                                                    
 443              android.os.Debug.startMethodTracing(                                                                  
 444                      Environment.getExternalStorageDirectory() + "/launcher");                                     
 445          }                                                                                                         
 446                                                                                                                    
 447          checkForLocaleChange();                                                                                   
 448          setContentView(R.layout.launcher);                                                                        
 449                                                                                                                    
 450          setupViews();                                                                                             
 451          grid.layout(this);                                                                                        
 452                                                                                                                    
 453          registerContentObservers();                                                                               
 454                                                                                                                    
 455          lockAllApps();                                                                                            
 456                                                                                                                    
 457          mSavedState = savedInstanceState;                                                                         
 458          restoreState(mSavedState);                                                                                
 459                                                                                                                    
 460          if (PROFILE_STARTUP) {                                                                                    
 461              android.os.Debug.stopMethodTracing();                                                                 
 462          }                                                                                                         
 463                                                                                                                    
 464          if (!mRestoring) {                                                                                        
 465              if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {                                                       
 466                  // If the user leaves launcher, then we should just load items asynchronously when                
 467                  // they return.                                                                                   
 468                  mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                         
 469              } else {                                                                                              
 470                  // We only load the page synchronously if the user rotates (or triggers a                         
 471                  // configuration change) while launcher is in the foreground                                      
 472                  mModel.startLoader(true, mWorkspace.getRestorePage());                                            
 473              }                                                                                                     
 474          }                                                                                                         
 475                                                                                                                    
 476          // For handling default keys                                                                              
 477          mDefaultKeySsb = new SpannableStringBuilder();                                                            
 478          Selection.setSelection(mDefaultKeySsb, 0);                                                                
 479                                                                                                                    
 480          IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);                               
 481          registerReceiver(mCloseSystemDialogsReceiver, filter);                                                    
 482                                                                                                                    
 483          // On large interfaces, we want the screen to auto-rotate based on the current orientation                
 484          unlockScreenOrientation(true);                                                                            
 485                                                                                                                    
 486          if (mLauncherCallbacks != null) {                                                                         
 487              mLauncherCallbacks.onCreate(savedInstanceState);                                                      
 488              if (mLauncherCallbacks.hasLauncherOverlay()) {                                                        
 489                  ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);                              
 490                  mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();                               
 491                  mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(                                     
 492                          mLauncherOverlayContainer, mLauncherOverlayCallbacks);                                    
 493                  mWorkspace.setLauncherOverlay(mLauncherOverlay);                                                  
 494              }                                                                                                     
 495          }                                                                                                         
 496                                                                                                                    
 497          if (shouldShowIntroScreen()) {                                                                            
 498              showIntroScreen();                                                                                    
 499          } else {                                                                                                  
 500              showFirstRunActivity();                                                                               
 501              showFirstRunClings();                                                                                 
 502          }                                                                                                         
 503      }                                                                                                             
 504                                                                                                                    
 505      private LauncherCallbacks mLauncherCallbacks;                                                                 
 506                                                                                                                    
 507      public void onPostCreate(Bundle savedInstanceState) {                                                         
 508          super.onPostCreate(savedInstanceState);                                                                   
 509          if (mLauncherCallbacks != null) {                                                                         
 510              mLauncherCallbacks.onPostCreate(savedInstanceState);                                                  
 511          }                                                                                                         
 512      }                                                                                                             
 513                                                                                                                    
 514      public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {                                            
 515          mLauncherCallbacks = callbacks;                                                                           











 516          return true;                                                                                              
 517      }                                                                                                             
 518                                                                                                                    
 519      @Override                                                                                                     
 520      public void onLauncherProviderChange() {                                                                      
 521          if (mLauncherCallbacks != null) {                                                                         
 522              mLauncherCallbacks.onLauncherProviderChange();                                                        
 523          }                                                                                                         
 524      }                                                                                                             
 525                                                                                                                    
 526      /** To be overridden by subclasses to hint to Launcher that we have custom content */                         
 527      protected boolean hasCustomContentToLeft() {                                                                  
 528          if (mLauncherCallbacks != null) {                                                                         
 529              return mLauncherCallbacks.hasCustomContentToLeft();                                                   
 530          }                                                                                                         
 531          return false;                                                                                             
 532      }                                                                                                             
 533                                                                                                                    
 534      /**                                                                                                           
 535       * To be overridden by subclasses to populate the custom content container and call                           
 536       * {@link #addToCustomContentPage}. This will only be invoked if                                              
 537       * {@link #hasCustomContentToLeft()} is {@code true}.                                                         
 538       */                                                                                                           
 539      protected void populateCustomContentContainer() {                                                             
 540          if (mLauncherCallbacks != null) {                                                                         
 541              mLauncherCallbacks.populateCustomContentContainer();                                                  
 542          }                                                                                                         
 543      }                                                                                                             
 544                                                                                                                    
 545      /**                                                                                                           
 546       * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to                   
 547       * ensure the custom content page is added or removed if necessary.                                           
 548       */                                                                                                           
 549      protected void invalidateHasCustomContentToLeft() {                                                           
 550          if (mWorkspace == null || mWorkspace.getScreenOrder().isEmpty()) {                                        
 551              // Not bound yet, wait for bindScreens to be called.                                                  
 552              return;                                                                                               
 553          }                                                                                                         
 554                                                                                                                    
 555          if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {                                         
 556              // Create the custom content page and call the subclass to populate it.                               
 557              mWorkspace.createCustomContentContainer();                                                            
 558              populateCustomContentContainer();                                                                     
 559          } else if (mWorkspace.hasCustomContent() && !hasCustomContentToLeft()) {                                  
 560              mWorkspace.removeCustomContentPage();                                                                 
 561          }                                                                                                         
 562      }                                                                                                             
 563                                                                                                                    
 564      private void checkForLocaleChange() {                                                                         

 565          if (sLocaleConfiguration == null) {                                                                       
 566              new AsyncTask<Void, Void, LocaleConfiguration>() {                                                    
 567                  @Override                                                                                         
 568                  protected LocaleConfiguration doInBackground(Void... unused) {                                    
 569                      LocaleConfiguration localeConfiguration = new LocaleConfiguration();                          
 570                      readConfiguration(Launcher.this, localeConfiguration);                                        
 571                      return localeConfiguration;                                                                   
 572                  }                                                                                                 
 573                                                                                                                    
 574                  @Override                                                                                         
 575                  protected void onPostExecute(LocaleConfiguration result) {                                        
 576                      sLocaleConfiguration = result;                                                                
 577                      checkForLocaleChange();  // recursive, but now with a locale configuration                    
 578                  }                                                                                                 
 579              }.execute();                                                                                          
 580              return;                                                                                               
 581          }                                                                                                         
 582                                                                                                                    
 583          final Configuration configuration = getResources().getConfiguration();                                    
 584                                                                                                                    
 585          final String previousLocale = sLocaleConfiguration.locale;                                                
 586          final String locale = configuration.locale.toString();                                                    
 587                                                                                                                    
 588          final int previousMcc = sLocaleConfiguration.mcc;                                                         
 589          final int mcc = configuration.mcc;                                                                        
 590                                                                                                                    
 591          final int previousMnc = sLocaleConfiguration.mnc;                                                         
 592          final int mnc = configuration.mnc;                                                                        
 593                                                                                                                    
 594          boolean localeChanged = !locale.equals(previousLocale) || mcc != previousMcc || mnc != previousMnc;       
 595                                                                                                                    
 596          if (localeChanged) {                                                                                      
 597              sLocaleConfiguration.locale = locale;                                                                 
 598              sLocaleConfiguration.mcc = mcc;                                                                       
 599              sLocaleConfiguration.mnc = mnc;                                                                       
 600                                                                                                                    
 601              mIconCache.flush();                                                                                   
 602                                                                                                                    
 603              final LocaleConfiguration localeConfiguration = sLocaleConfiguration;                                 
 604              new AsyncTask<Void, Void, Void>() {                                                                   
 605                  public Void doInBackground(Void ... args) {                                                       
 606                      writeConfiguration(Launcher.this, localeConfiguration);                                       
 607                      return null;                                                                                  
 608                  }                                                                                                 
 609              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
 610          }                                                                                                         
 611      }                                                                                                             
 612                                                                                                                    
 613      private static class LocaleConfiguration {                                                                    

 614          public String locale;                                                                                     
 615          public int mcc = -1;                                                                                      
 616          public int mnc = -1;                                                                                      
 617      }                                                                                                             
 618                                                                                                                    
 619      private static void readConfiguration(Context context, LocaleConfiguration configuration) {                   

 620          DataInputStream in = null;                                                                                
 621          try {                                                                                                     
 622              in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));                  
 623              configuration.locale = in.readUTF();                                                                  
 624              configuration.mcc = in.readInt();                                                                     
 625              configuration.mnc = in.readInt();                                                                     
 626          } catch (FileNotFoundException e) {                                                                       
 627              // Ignore                                                                                             
 628          } catch (IOException e) {                                                                                 
 629              // Ignore                                                                                             
 630          } finally {                                                                                               
 631              if (in != null) {                                                                                     
 632                  try {                                                                                             
 633                      in.close();                                                                                   
 634                  } catch (IOException e) {                                                                         
 635                      // Ignore                                                                                     
 636                  }                                                                                                 
 637              }                                                                                                     
 638          }                                                                                                         
 639      }                                                                                                             
 640                                                                                                                    
 641      private static void writeConfiguration(Context context, LocaleConfiguration configuration) {                  

 642          DataOutputStream out = null;                                                                              
 643          try {                                                                                                     
 644              out = new DataOutputStream(context.openFileOutput(                                                    
 645                      LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));                                           
 646              out.writeUTF(configuration.locale);                                                                   
 647              out.writeInt(configuration.mcc);                                                                      
 648              out.writeInt(configuration.mnc);                                                                      
 649              out.flush();                                                                                          
 650          } catch (FileNotFoundException e) {                                                                       
 651              // Ignore                                                                                             
 652          } catch (IOException e) {                                                                                 
 653              //noinspection ResultOfMethodCallIgnored                                                              
 654              context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();                               
 655          } finally {                                                                                               
 656              if (out != null) {                                                                                    
 657                  try {                                                                                             
 658                      out.close();                                                                                  
 659                  } catch (IOException e) {                                                                         
 660                      // Ignore                                                                                     
 661                  }                                                                                                 
 662              }                                                                                                     
 663          }                                                                                                         
 664      }                                                                                                             
 665                                                                                                                    
 666      public Stats getStats() {                                                                                     
 667          return mStats;                                                                                            
 668      }                                                                                                             
 669                                                                                                                    
 670      public LayoutInflater getInflater() {                                                                         
 671          return mInflater;                                                                                         
 672      }                                                                                                             
 673                                                                                                                    
 674      boolean isDraggingEnabled() {                                                                                 

 675          // We prevent dragging when we are loading the workspace as it is possible to pick up a view              
 676          // that is subsequently removed from the workspace in startBinding().                                     
 677          return !mModel.isLoadingWorkspace();                                                                      
 678      }                                                                                                             
 679                                                                                                                    
 680      @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)                                                                
 681      public static int generateViewId() {                                                                          
 682          if (Build.VERSION.SDK_INT >= 17) {                                                                        
 683              return View.generateViewId();                                                                         
 684          } else {                                                                                                  
 685              // View.generateViewId() is not available. The following fallback logic is a copy                     
 686              // of its implementation.                                                                             
 687              for (;;) {                                                                                            
 688                  final int result = sNextGeneratedId.get();                                                        
 689                  // aapt-generated IDs have the high byte nonzero; clamp to the range under that.                  
 690                  int newValue = result + 1;                                                                        
 691                  if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.                                
 692                  if (sNextGeneratedId.compareAndSet(result, newValue)) {                                           
 693                      return result;                                                                                
 694                  }                                                                                                 
 695              }                                                                                                     
 696          }                                                                                                         
 697      }                                                                                                             
 698                                                                                                                    
 699      public int getViewIdForItem(ItemInfo info) {                                                                  
 700          // This cast is safe given the > 2B range for int.                                                        
 701          int itemId = (int) info.id;                                                                               
 702          if (mItemIdToViewId.containsKey(itemId)) {                                                                
 703              return mItemIdToViewId.get(itemId);                                                                   
 704          }                                                                                                         
 705          int viewId = generateViewId();                                                                            
 706          mItemIdToViewId.put(itemId, viewId);                                                                      
 707          return viewId;                                                                                            
 708      }                                                                                                             
 709                                                                                                                    
 710      /**                                                                                                           
 711       * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have                  
 712       * a configuration step, this allows the proper animations to run after other transitions.                    
 713       */                                                                                                           
 714      private long completeAdd(PendingAddArguments args) {                                                          
 715          long screenId = args.screenId;                                                                            
 716          if (args.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                                     
 717              // When the screen id represents an actual screen (as opposed to a rank) we make sure                 
 718              // that the drop page actually exists.                                                                
 719              screenId = ensurePendingDropLayoutExists(args.screenId);                                              
 720          }                                                                                                         
 721                                                                                                                    
 722          switch (args.requestCode) {                                                                               
 723              case REQUEST_CREATE_SHORTCUT:                                                                         
 724                  completeAddShortcut(args.intent, args.container, screenId, args.cellX,                            
 725                          args.cellY);                                                                              
 726                  break;                                                                                            
 727              case REQUEST_CREATE_APPWIDGET:                                                                        
 728                  completeAddAppWidget(args.appWidgetId, args.container, screenId, null, null);                     
 729                  break;                                                                                            
 730              case REQUEST_RECONFIGURE_APPWIDGET:                                                                   
 731                  completeRestoreAppWidget(args.appWidgetId);                                                       
 732                  break;                                                                                            
 733          }                                                                                                         
 734          // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,                   
 735          // if you turned the screen off and then back while in All Apps, Launcher would not                       
 736          // return to the workspace. Clearing mAddInfo.container here fixes this issue                             
 737          resetAddInfo();                                                                                           
 738          return screenId;                                                                                          
 739      }                                                                                                             
 740                                                                                                                    
 741      private void handleActivityResult(                                                                            
 742              final int requestCode, final int resultCode, final Intent data) {                                     
 743          // Reset the startActivity waiting flag                                                                   
 744          setWaitingForResult(false);                                                                               
 745          final int pendingAddWidgetId = mPendingAddWidgetId;                                                       
 746          mPendingAddWidgetId = -1;                                                                                 
 747                                                                                                                    
 748          Runnable exitSpringLoaded = new Runnable() {                                                              
 749              @Override                                                                                             
 750              public void run() {                                                                                   
 751                  exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                                  
 752                          EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                              
 753              }                                                                                                     
 754          };                                                                                                        
 755                                                                                                                    
 756          if (requestCode == REQUEST_BIND_APPWIDGET) {                                                              
 757              final int appWidgetId = data != null ?                                                                
 758                      data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;                               
 759              if (resultCode == RESULT_CANCELED) {                                                                  
 760                  completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);                                         
 761                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 762                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 763              } else if (resultCode == RESULT_OK) {                                                                 
 764                  addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,                                              
 765                          mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                               
 766              }                                                                                                     
 767              return;                                                                                               
 768          } else if (requestCode == REQUEST_PICK_WALLPAPER) {                                                       
 769              if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {                                       
 770                  mWorkspace.exitOverviewMode(false);                                                               
 771              }                                                                                                     
 772              return;                                                                                               
 773          }                                                                                                         
 774                                                                                                                    
 775          boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||                                          
 776                  requestCode == REQUEST_CREATE_APPWIDGET);                                                         
 777                                                                                                                    
 778          final boolean workspaceLocked = isWorkspaceLocked();                                                      
 779          // We have special handling for widgets                                                                   
 780          if (isWidgetDrop) {                                                                                       
 781              final int appWidgetId;                                                                                
 782              int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)               
 783                      : -1;                                                                                         
 784              if (widgetId < 0) {                                                                                   
 785                  appWidgetId = pendingAddWidgetId;                                                                 
 786              } else {                                                                                              
 787                  appWidgetId = widgetId;                                                                           
 788              }                                                                                                     
 789                                                                                                                    
 790              final int result;                                                                                     
 791              if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {                                               
 792                  Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not " +                                   
 793                          "returned from the widget configuration activity.");                                      
 794                  result = RESULT_CANCELED;                                                                         
 795                  completeTwoStageWidgetDrop(result, appWidgetId);                                                  
 796                  final Runnable onComplete = new Runnable() {                                                      
 797                      @Override                                                                                     
 798                      public void run() {                                                                           
 799                          exitSpringLoadedDragModeDelayed(false, 0, null);                                          
 800                      }                                                                                             
 801                  };                                                                                                
 802                  if (workspaceLocked) {                                                                            
 803                      // No need to remove the empty screen if we're mid-binding, as the                            
 804                      // the bind will not add the empty screen.                                                    
 805                      mWorkspace.postDelayed(onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY);                       
 806                  } else {                                                                                          
 807                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 808                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 809                  }                                                                                                 
 810              } else {                                                                                              
 811                  if (!workspaceLocked) {                                                                           
 812                      if (mPendingAddInfo.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {              
 813                          // When the screen id represents an actual screen (as opposed to a rank)                  
 814                          // we make sure that the drop page actually exists.                                       
 815                          mPendingAddInfo.screenId =                                                                
 816                                  ensurePendingDropLayoutExists(mPendingAddInfo.screenId);                          
 817                      }                                                                                             
 818                      final CellLayout dropLayout = mWorkspace.getScreenWithId(mPendingAddInfo.screenId);           
 819                                                                                                                    
 820                      dropLayout.setDropPending(true);                                                              
 821                      final Runnable onComplete = new Runnable() {                                                  
 822                          @Override                                                                                 
 823                          public void run() {                                                                       
 824                              completeTwoStageWidgetDrop(resultCode, appWidgetId);                                  
 825                              dropLayout.setDropPending(false);                                                     
 826                          }                                                                                         
 827                      };                                                                                            
 828                      mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,                                    
 829                              ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                           
 830                  } else {                                                                                          
 831                      PendingAddArguments args = preparePendingAddArgs(requestCode, data, appWidgetId,              
 832                              mPendingAddInfo);                                                                     
 833                      sPendingAddItem = args;                                                                       
 834                  }                                                                                                 
 835              }                                                                                                     
 836              return;                                                                                               
 837          }                                                                                                         
 838                                                                                                                    
 839          if (requestCode == REQUEST_RECONFIGURE_APPWIDGET) {                                                       
 840              if (resultCode == RESULT_OK) {                                                                        
 841                  // Update the widget view.                                                                        
 842                  PendingAddArguments args = preparePendingAddArgs(requestCode, data,                               
 843                          pendingAddWidgetId, mPendingAddInfo);                                                     
 844                  if (workspaceLocked) {                                                                            
 845                      sPendingAddItem = args;                                                                       
 846                  } else {                                                                                          
 847                      completeAdd(args);                                                                            
 848                  }                                                                                                 
 849              }                                                                                                     
 850              // Leave the widget in the pending state if the user canceled the configure.                          
 851              return;                                                                                               
 852          }                                                                                                         
 853                                                                                                                    
 854          // The pattern used here is that a user PICKs a specific application,                                     
 855          // which, depending on the target, might need to CREATE the actual target.                                
 856                                                                                                                    
 857          // For example, the user would PICK_SHORTCUT for "Music playlist", and we                                 
 858          // launch over to the Music app to actually CREATE_SHORTCUT.                                              
 859          if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID) {                             
 860              final PendingAddArguments args = preparePendingAddArgs(requestCode, data, -1,                         
 861                      mPendingAddInfo);                                                                             
 862              if (isWorkspaceLocked()) {                                                                            
 863                  sPendingAddItem = args;                                                                           
 864              } else {                                                                                              
 865                  completeAdd(args);                                                                                
 866                  mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                  
 867                          ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                               
 868              }                                                                                                     
 869          } else if (resultCode == RESULT_CANCELED) {                                                               
 870              mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,                                      
 871                      ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);                                                   
 872          }                                                                                                         
 873          mDragLayer.clearAnimatedView();                                                                           
 874                                                                                                                    
 875      }                                                                                                             
 876                                                                                                                    
 877      @Override                                                                                                     
 878      protected void onActivityResult(                                                                              
 879              final int requestCode, final int resultCode, final Intent data) {                                     
 880          handleActivityResult(requestCode, resultCode, data);                                                      
 881          if (mLauncherCallbacks != null) {                                                                         
 882              mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);                                   
 883          }                                                                                                         
 884      }                                                                                                             
 885                                                                                                                    
 886      private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int                           
 887              appWidgetId, ItemInfo info) {                                                                         
 888          PendingAddArguments args = new PendingAddArguments();                                                     
 889          args.requestCode = requestCode;                                                                           
 890          args.intent = data;                                                                                       
 891          args.container = info.container;                                                                          
 892          args.screenId = info.screenId;                                                                            
 893          args.cellX = info.cellX;                                                                                  
 894          args.cellY = info.cellY;                                                                                  
 895          args.appWidgetId = appWidgetId;                                                                           
 896          return args;                                                                                              
 897      }                                                                                                             
 898                                                                                                                    
 899      /**                                                                                                           
 900       * Check to see if a given screen id exists. If not, create it at the end, return the new id.                 
 901       *                                                                                                            
 902       * @param screenId the screen id to check                                                                     
 903       * @return the new screen, or screenId if it exists                                                           
 904       */                                                                                                           
 905      private long ensurePendingDropLayoutExists(long screenId) {                                                   
 906          CellLayout dropLayout =                                                                                   
 907                  (CellLayout) mWorkspace.getScreenWithId(screenId);                                                
 908          if (dropLayout == null) {                                                                                 
 909              // it's possible that the add screen was removed because it was                                       
 910              // empty and a re-bind occurred                                                                       
 911              mWorkspace.addExtraEmptyScreen();                                                                     
 912              return mWorkspace.commitExtraEmptyScreen();                                                           
 913          } else {                                                                                                  
 914              return screenId;                                                                                      
 915          }                                                                                                         
 916      }                                                                                                             
 917                                                                                                                    
 918      private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {                        

 919          CellLayout cellLayout =                                                                                   
 920                  (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);                                
 921          Runnable onCompleteRunnable = null;                                                                       
 922          int animationType = 0;                                                                                    
 923                                                                                                                    
 924          AppWidgetHostView boundWidget = null;                                                                     
 925          if (resultCode == RESULT_OK) {                                                                            
 926              animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;                                   
 927              final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,                         
 928                      mPendingAddWidgetInfo);                                                                       
 929              boundWidget = layout;                                                                                 
 930              onCompleteRunnable = new Runnable() {                                                                 
 931                  @Override                                                                                         
 932                  public void run() {                                                                               
 933                      completeAddAppWidget(appWidgetId, mPendingAddInfo.container,                                  
 934                              mPendingAddInfo.screenId, layout, null);                                              
 935                      exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),                              
 936                              EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);                                          
 937                  }                                                                                                 
 938              };                                                                                                    
 939          } else if (resultCode == RESULT_CANCELED) {                                                               
 940              mAppWidgetHost.deleteAppWidgetId(appWidgetId);                                                        
 941              animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;                                     
 942          }                                                                                                         
 943          if (mDragLayer.getAnimatedView() != null) {                                                               
 944              mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,                                             
 945                      (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,                                  
 946                      animationType, boundWidget, true);                                                            
 947          } else if (onCompleteRunnable != null) {                                                                  
 948              // The animated view may be null in the case of a rotation during widget configuration                
 949              onCompleteRunnable.run();                                                                             
 950          }                                                                                                         
 951      }                                                                                                             
 952                                                                                                                    
 953      @Override                                                                                                     
 954      protected void onStop() {                                                                                     
 955          super.onStop();                                                                                           
 956          FirstFrameAnimatorHelper.setIsVisible(false);                                                             
 957                                                                                                                    
 958          if (mLauncherCallbacks != null) {                                                                         
 959              mLauncherCallbacks.onStop();                                                                          
 960          }                                                                                                         
 961      }                                                                                                             
 962                                                                                                                    
 963      @Override                                                                                                     
 964      protected void onStart() {                                                                                    
 965          super.onStart();                                                                                          
 966          FirstFrameAnimatorHelper.setIsVisible(true);                                                              
 967                                                                                                                    
 968          if (mLauncherCallbacks != null) {                                                                         
 969              mLauncherCallbacks.onStart();                                                                         
 970          }                                                                                                         
 971      }                                                                                                             
 972                                                                                                                    
 973      @Override                                                                                                     
 974      protected void onResume() {                                                                                   
 975          long startTime = 0;                                                                                       
 976          if (DEBUG_RESUME_TIME) {                                                                                  
 977              startTime = System.currentTimeMillis();                                                               
 978              Log.v(TAG, "Launcher.onResume()");                                                                    
 979          }                                                                                                         
 980                                                                                                                    
 981          if (mLauncherCallbacks != null) {                                                                         
 982              mLauncherCallbacks.preOnResume();                                                                     
 983          }                                                                                                         
 984                                                                                                                    
 985          super.onResume();                                                                                         
 986                                                                                                                    
 987          // Restore the previous launcher state                                                                    
 988          if (mOnResumeState == State.WORKSPACE) {                                                                  
 989              showWorkspace(false);                                                                                 
 990          } else if (mOnResumeState == State.APPS_CUSTOMIZE) {                                                      
 991              showAllApps(false, mAppsCustomizeContent.getContentType(), false);                                    




 992          }                                                                                                         
 993          mOnResumeState = State.NONE;                                                                              
 994                                                                                                                    
 995          // Background was set to gradient in onPause(), restore to black if in all apps.                          
 996          setWorkspaceBackground(mState == State.WORKSPACE);                                                        
 997                                                                                                                    
 998          mPaused = false;                                                                                          
 999          if (mRestoring || mOnResumeNeedsLoad) {                                                                   
1000              setWorkspaceLoading(true);                                                                            
1001              mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);                                             
1002              mRestoring = false;                                                                                   
1003              mOnResumeNeedsLoad = false;                                                                           
1004          }                                                                                                         
1005          if (mBindOnResumeCallbacks.size() > 0) {                                                                  
1006              // We might have postponed some bind calls until onResume (see waitUntilResume) --                    
1007              // execute them here                                                                                  
1008              long startTimeCallbacks = 0;                                                                          
1009              if (DEBUG_RESUME_TIME) {                                                                              
1010                  startTimeCallbacks = System.currentTimeMillis();                                                  
1011              }                                                                                                     
1012                                                                                                                    
1013              if (mAppsCustomizeContent != null) {                                                                  
1014                  mAppsCustomizeContent.setBulkBind(true);                                                          
1015              }                                                                                                     
1016              for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {                                             
1017                  mBindOnResumeCallbacks.get(i).run();                                                              
1018              }                                                                                                     
1019              if (mAppsCustomizeContent != null) {                                                                  
1020                  mAppsCustomizeContent.setBulkBind(false);                                                         
1021              }                                                                                                     
1022              mBindOnResumeCallbacks.clear();                                                                       
1023              if (DEBUG_RESUME_TIME) {                                                                              
1024                  Log.d(TAG, "Time spent processing callbacks in onResume: " +                                      
1025                      (System.currentTimeMillis() - startTimeCallbacks));                                           
1026              }                                                                                                     
1027          }                                                                                                         
1028          if (mOnResumeCallbacks.size() > 0) {                                                                      
1029              for (int i = 0; i < mOnResumeCallbacks.size(); i++) {                                                 
1030                  mOnResumeCallbacks.get(i).run();                                                                  
1031              }                                                                                                     
1032              mOnResumeCallbacks.clear();                                                                           
1033          }                                                                                                         
1034                                                                                                                    
1035          // Reset the pressed state of icons that were locked in the press state while activities                  
1036          // were launching                                                                                         
1037          if (mWaitingForResume != null) {                                                                          
1038              // Resets the previous workspace icon press state                                                     
1039              mWaitingForResume.setStayPressed(false);                                                              
1040          }                                                                                                         
1041                                                                                                                    
1042          // It is possible that widgets can receive updates while launcher is not in the foreground.               
1043          // Consequently, the widgets will be inflated in the orientation of the foreground activity               
1044          // (framework issue). On resuming, we ensure that any widgets are inflated for the current                
1045          // orientation.                                                                                           
1046          getWorkspace().reinflateWidgetsIfNecessary();                                                             

1047                                                                                                                    
1048          // Process any items that were added while Launcher was away.                                             
1049          InstallShortcutReceiver.disableAndFlushInstallQueue(this);                                                
1050                                                                                                                    
1051          if (DEBUG_RESUME_TIME) {                                                                                  
1052              Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));                    
1053          }                                                                                                         
1054                                                                                                                    
1055          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1056              // If we are resuming and the custom content is the current page, we call onShow().                   
1057              // It is also poassible that onShow will instead be called slightly after first layout                
1058              // if PagedView#setRestorePage was set to the custom content page in onCreate().                      
1059              if (mWorkspace.isOnOrMovingToCustomContent()) {                                                       
1060                  mWorkspace.getCustomContentCallbacks().onShow(true);                                              
1061              }                                                                                                     
1062          }                                                                                                         
1063          mWorkspace.updateInteractionForState();                                                                   
1064          mWorkspace.onResume();                                                                                    
1065                                                                                                                    
1066          PackageInstallerCompat.getInstance(this).onResume();                                                      
1067                                                                                                                    
1068          if (mLauncherCallbacks != null) {                                                                         
1069              mLauncherCallbacks.onResume();                                                                        
1070          }                                                                                                         
1071      }                                                                                                             
1072                                                                                                                    
1073      @Override                                                                                                     
1074      protected void onPause() {                                                                                    
1075          // Ensure that items added to Launcher are queued until Launcher returns                                  
1076          InstallShortcutReceiver.enableInstallQueue();                                                             
1077          PackageInstallerCompat.getInstance(this).onPause();                                                       
1078                                                                                                                    
1079          super.onPause();                                                                                          
1080          mPaused = true;                                                                                           
1081          mDragController.cancelDrag();                                                                             
1082          mDragController.resetLastGestureUpTime();                                                                 
1083                                                                                                                    
1084          // We call onHide() aggressively. The custom content callbacks should be able to                          
1085          // debounce excess onHide calls.                                                                          
1086          if (mWorkspace.getCustomContentCallbacks() != null) {                                                     
1087              mWorkspace.getCustomContentCallbacks().onHide();                                                      
1088          }                                                                                                         
1089                                                                                                                    
1090          if (mLauncherCallbacks != null) {                                                                         
1091              mLauncherCallbacks.onPause();                                                                         
1092          }                                                                                                         
1093      }                                                                                                             
1094                                                                                                                    
1095      public interface CustomContentCallbacks {                                                                     
1096          // Custom content is completely shown. {@code fromResume} indicates whether this was caused               
1097          // by a onResume or by scrolling otherwise.                                                               
1098          public void onShow(boolean fromResume);                                                                   
1099                                                                                                                    
1100          // Custom content is completely hidden                                                                    
1101          public void onHide();                                                                                     
1102                                                                                                                    
1103          // Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).                     
1104          public void onScrollProgressChanged(float progress);                                                      
1105                                                                                                                    
1106          // Indicates whether the user is allowed to scroll away from the custom content.                          
1107          boolean isScrollingAllowed();                                                                             
1108      }                                                                                                             
1109                                                                                                                    
1110      public interface LauncherOverlay {                                                                            
1111                                                                                                                    
1112          /**                                                                                                       
1113           * Touch interaction leading to overscroll has begun                                                      
1114           */                                                                                                       
1115          public void onScrollInteractionBegin();                                                                   
1116                                                                                                                    
1117          /**                                                                                                       
1118           * Touch interaction related to overscroll has ended                                                      
1119           */                                                                                                       
1120          public void onScrollInteractionEnd();                                                                     
1121                                                                                                                    
1122          /**                                                                                                       
1123           * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost                          
1124           * screen (or in the case of RTL, the rightmost screen).                                                  
1125           */                                                                                                       
1126          public void onScrollChange(int progress, boolean rtl);                                                    
1127                                                                                                                    
1128          /**                                                                                                       
1129           * Screen has stopped scrolling                                                                           
1130           */                                                                                                       
1131          public void onScrollSettled();                                                                            
1132                                                                                                                    
1133          /**                                                                                                       
1134           * This method can be called by the Launcher in order to force the LauncherOverlay                        
1135           * to exit fully immersive mode.                                                                          
1136           */                                                                                                       
1137          public void forceExitFullImmersion();                                                                     













1138      }                                                                                                             
1139                                                                                                                    
1140      public interface LauncherOverlayCallbacks {                                                                   
1141          /**                                                                                                       
1142           * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,                    
1143           * however it doesn't modify any state within the launcher.                                               
1144           */                                                                                                       
1145          public boolean canEnterFullImmersion();                                                                   
1146                                                                                                                    
1147          /**                                                                                                       
1148           * Should be called to tell Launcher that the LauncherOverlay will take over interaction,                 
1149           * eg. by occupying the full screen and handling all touch events.                                        
1150           *                                                                                                        
1151           * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this                 
1152           *          case, Launcher will modify any necessary state and assumes the overlay is                     
1153           *          handling all interaction. If false, the LauncherOverlay should cancel any                     
1154           *                                                                                                        
1155           */                                                                                                       
1156          public boolean enterFullImmersion();                                                                      
1157                                                                                                                    
1158          /**                                                                                                       
1159           * Must be called when exiting fully immersive mode. Indicates to Launcher that it has                    
1160           * full control over UI and state.                                                                        
1161           */                                                                                                       
1162          public void exitFullImmersion();                                                                          
1163      }                                                                                                             
1164                                                                                                                    
1165      class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {                                      
1166                                                                                                                    
1167          @Override                                                                                                 
1168          public boolean canEnterFullImmersion() {                                                                  
1169              return mState == State.WORKSPACE;                                                                     
1170          }                                                                                                         
1171                                                                                                                    
1172          @Override                                                                                                 
1173          public boolean enterFullImmersion() {                                                                     
1174              if (mState == State.WORKSPACE) {                                                                      
1175                  // When fully immersed, disregard any touches which fall through.                                 
1176                  mDragLayer.setBlockTouch(true);                                                                   
1177                  return true;                                                                                      
1178              }                                                                                                     
1179              return false;                                                                                         
1180          }                                                                                                         
1181                                                                                                                    
1182          @Override                                                                                                 
1183          public void exitFullImmersion() {                                                                         
1184              mDragLayer.setBlockTouch(false);                                                                      
1185          }                                                                                                         
1186      }                                                                                                             
1187                                                                                                                    
1188      protected boolean hasSettings() {                                                                             
1189          if (mLauncherCallbacks != null) {                                                                         
1190              return mLauncherCallbacks.hasSettings();                                                              
1191          }                                                                                                         
1192          return false;                                                                                             
1193      }                                                                                                             
1194                                                                                                                    
1195                                                                                                                    
1196      public void addToCustomContentPage(View customContent,                                                        
1197              CustomContentCallbacks callbacks, String description) {                                               
1198          mWorkspace.addToCustomContentPage(customContent, callbacks, description);                                 
1199      }                                                                                                             
1200                                                                                                                    
1201      // The custom content needs to offset its content to account for the QSB                                      
1202      public int getTopOffsetForCustomContent() {                                                                   
1203          return mWorkspace.getPaddingTop();                                                                        
1204      }                                                                                                             
1205                                                                                                                    
1206      @Override                                                                                                     
1207      public Object onRetainNonConfigurationInstance() {                                                            
1208          // Flag the loader to stop early before switching                                                         
1209          if (mModel.isCurrentCallbacks(this)) {                                                                    
1210              mModel.stopLoader();                                                                                  
1211          }                                                                                                         
1212          if (mAppsCustomizeContent != null) {                                                                      
1213              mAppsCustomizeContent.surrender();                                                                    
1214          }                                                                                                         


1215          return Boolean.TRUE;                                                                                      
1216      }                                                                                                             
1217                                                                                                                    
1218      // We can't hide the IME if it was forced open.  So don't bother                                              
1219      @Override                                                                                                     
1220      public void onWindowFocusChanged(boolean hasFocus) {                                                          
1221          super.onWindowFocusChanged(hasFocus);                                                                     
1222          mHasFocus = hasFocus;                                                                                     
1223                                                                                                                    
1224          if (mLauncherCallbacks != null) {                                                                         
1225              mLauncherCallbacks.onWindowFocusChanged(hasFocus);                                                    
1226          }                                                                                                         
1227      }                                                                                                             
1228                                                                                                                    
1229      private boolean acceptFilter() {                                                                              
1230          final InputMethodManager inputManager = (InputMethodManager)                                              
1231                  getSystemService(Context.INPUT_METHOD_SERVICE);                                                   
1232          return !inputManager.isFullscreenMode();                                                                  
1233      }                                                                                                             
1234                                                                                                                    
1235      @Override                                                                                                     
1236      public boolean onKeyDown(int keyCode, KeyEvent event) {                                                       
1237          final int uniChar = event.getUnicodeChar();                                                               
1238          final boolean handled = super.onKeyDown(keyCode, event);                                                  
1239          final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);                       
1240          if (!handled && acceptFilter() && isKeyNotWhitespace) {                                                   
1241              boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,                  
1242                      keyCode, event);                                                                              
1243              if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {                                
1244                  // something usable has been typed - start a search                                               
1245                  // the typed text will be retrieved and cleared by                                                
1246                  // showSearchDialog()                                                                             
1247                  // If there are multiple keystrokes before the search dialog takes focus,                         
1248                  // onSearchRequested() will be called for every keystroke,                                        
1249                  // but it is idempotent, so it's fine.                                                            
1250                  return onSearchRequested();                                                                       
1251              }                                                                                                     
1252          }                                                                                                         
1253                                                                                                                    
1254          // Eat the long press event so the keyboard doesn't come up.                                              
1255          if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {                                            
1256              return true;                                                                                          
1257          }                                                                                                         
1258                                                                                                                    
1259          return handled;                                                                                           
1260      }                                                                                                             
1261                                                                                                                    
1262      private String getTypedText() {                                                                               
1263          return mDefaultKeySsb.toString();                                                                         
1264      }                                                                                                             
1265                                                                                                                    
1266      private void clearTypedText() {                                                                               
1267          mDefaultKeySsb.clear();                                                                                   
1268          mDefaultKeySsb.clearSpans();                                                                              
1269          Selection.setSelection(mDefaultKeySsb, 0);                                                                
1270      }                                                                                                             
1271                                                                                                                    
1272      /**                                                                                                           
1273       * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type               
1274       * State                                                                                                      
1275       */                                                                                                           
1276      private static State intToState(int stateOrdinal) {                                                           
1277          State state = State.WORKSPACE;                                                                            
1278          final State[] stateValues = State.values();                                                               
1279          for (int i = 0; i < stateValues.length; i++) {                                                            
1280              if (stateValues[i].ordinal() == stateOrdinal) {                                                       
1281                  state = stateValues[i];                                                                           
1282                  break;                                                                                            
1283              }                                                                                                     
1284          }                                                                                                         
1285          return state;                                                                                             
1286      }                                                                                                             
1287                                                                                                                    
1288      /**                                                                                                           
1289       * Restores the previous state, if it exists.                                                                 
1290       *                                                                                                            
1291       * @param savedState The previous state.                                                                      
1292       */                                                                                                           
1293      @SuppressWarnings("unchecked")                                                                                
1294      private void restoreState(Bundle savedState) {                                                                
1295          if (savedState == null) {                                                                                 
1296              return;                                                                                               
1297          }                                                                                                         
1298                                                                                                                    
1299          State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));                    
1300          if (state == State.APPS_CUSTOMIZE) {                                                                      
1301              mOnResumeState = State.APPS_CUSTOMIZE;                                                                


1302          }                                                                                                         
1303                                                                                                                    
1304          int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN,                                       
1305                  PagedView.INVALID_RESTORE_PAGE);                                                                  
1306          if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {                                                    
1307              mWorkspace.setRestorePage(currentScreen);                                                             
1308          }                                                                                                         
1309                                                                                                                    
1310          final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);             
1311          final long pendingAddScreen = savedState.getLong(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);                   
1312                                                                                                                    
1313          if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {                                     
1314              mPendingAddInfo.container = pendingAddContainer;                                                      
1315              mPendingAddInfo.screenId = pendingAddScreen;                                                          
1316              mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X);                          
1317              mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y);                          
1318              mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);                          
1319              mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);                          
1320              AppWidgetProviderInfo info = savedState.getParcelable(                                                
1321                      RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);                                                       
1322              mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this, info);                   
1323              mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);                         
1324              setWaitingForResult(true);                                                                            
1325              mRestoring = true;                                                                                    
1326          }                                                                                                         
1327                                                                                                                    
1328          boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false);                 
1329          if (renameFolder) {                                                                                       
1330              long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID);                                 
1331              mFolderInfo = mModel.getFolderById(this, sFolders, id);                                               
1332              mRestoring = true;                                                                                    
1333          }                                                                                                         
1334                                                                                                                    
1335          // Restore the AppsCustomize tab                                                                          
1336          if (mAppsCustomizeTabHost != null) {                                                                      
1337              String curTab = savedState.getString("apps_customize_currentTab");                                    
1338              if (curTab != null) {                                                                                 
1339                  mAppsCustomizeTabHost.setContentTypeImmediate(                                                    
1340                          mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));                                   
1341                  mAppsCustomizeContent.loadAssociatedPages(                                                        
1342                          mAppsCustomizeContent.getCurrentPage());                                                  
1343              }                                                                                                     
1344                                                                                                                    
1345              int currentIndex = savedState.getInt("apps_customize_currentIndex");                                  
1346              mAppsCustomizeContent.restorePageForIndex(currentIndex);                                              
1347          }                                                                                                         
1348          mItemIdToViewId = (HashMap<Integer, Integer>)                                                             
1349                  savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);                                               
1350      }                                                                                                             
1351                                                                                                                    
1352      /**                                                                                                           
1353       * Finds all the views we need and configure them properly.                                                   
1354       */                                                                                                           
1355      private void setupViews() {                                                                                   
1356          final DragController dragController = mDragController;                                                    
1357                                                                                                                    
1358          mLauncherView = findViewById(R.id.launcher);                                                              
1359          mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);                                  
1360          mDragLayer = (DragLayer) findViewById(R.id.drag_layer);                                                   
1361          mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);                                         
1362          mWorkspace.setPageSwitchListener(this);                                                                   
1363          mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);                                           
1364                                                                                                                    
1365          mLauncherView.setSystemUiVisibility(                                                                      
1366                  View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);              
1367          mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);                       
1368                                                                                                                    
1369          // Setup the drag layer                                                                                   
1370          mDragLayer.setup(this, dragController);                                                                   
1371                                                                                                                    
1372          // Setup the hotseat                                                                                      
1373          mHotseat = (Hotseat) findViewById(R.id.hotseat);                                                          
1374          if (mHotseat != null) {                                                                                   
1375              mHotseat.setup(this);                                                                                 
1376              mHotseat.setOnLongClickListener(this);                                                                
1377          }                                                                                                         
1378                                                                                                                    
1379          mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);                                           
1380          View widgetButton = findViewById(R.id.widget_button);                                                     
1381          widgetButton.setOnClickListener(new OnClickListener() {                                                   
1382              @Override                                                                                             
1383              public void onClick(View arg0) {                                                                      
1384                  if (!mWorkspace.isSwitchingState()) {                                                             
1385                      onClickAddWidgetButton(arg0);                                                                 
1386                  }                                                                                                 
1387              }                                                                                                     
1388          });                                                                                                       
1389          widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());                                        
1390                                                                                                                    
1391          View wallpaperButton = findViewById(R.id.wallpaper_button);                                               
1392          wallpaperButton.setOnClickListener(new OnClickListener() {                                                
1393              @Override                                                                                             
1394              public void onClick(View arg0) {                                                                      
1395                  if (!mWorkspace.isSwitchingState()) {                                                             
1396                      onClickWallpaperPicker(arg0);                                                                 
1397                  }                                                                                                 
1398              }                                                                                                     
1399          });                                                                                                       
1400          wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());                                     
1401                                                                                                                    
1402          View settingsButton = findViewById(R.id.settings_button);                                                 
1403          if (hasSettings()) {                                                                                      
1404              settingsButton.setOnClickListener(new OnClickListener() {                                             
1405                  @Override                                                                                         
1406                  public void onClick(View arg0) {                                                                  
1407                      if (!mWorkspace.isSwitchingState()) {                                                         
1408                          onClickSettingsButton(arg0);                                                              
1409                      }                                                                                             
1410                  }                                                                                                 
1411              });                                                                                                   
1412              settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());                                  
1413          } else {                                                                                                  
1414              settingsButton.setVisibility(View.GONE);                                                              
1415          }                                                                                                         
1416                                                                                                                    
1417          mOverviewPanel.setAlpha(0f);                                                                              
1418                                                                                                                    
1419          // Setup the workspace                                                                                    
1420          mWorkspace.setHapticFeedbackEnabled(false);                                                               
1421          mWorkspace.setOnLongClickListener(this);                                                                  
1422          mWorkspace.setup(dragController);                                                                         
1423          dragController.addDragListener(mWorkspace);                                                               
1424                                                                                                                    
1425          // Get the search/delete bar                                                                              
1426          mSearchDropTargetBar = (SearchDropTargetBar)                                                              
1427                  mDragLayer.findViewById(R.id.search_drop_target_bar);                                             
1428                                                                                                                    






1429          // Setup AppsCustomize                                                                                    
1430          mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);                    
1431          mAppsCustomizeContent = (AppsCustomizePagedView)                                                          
1432                  mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);                             
1433          mAppsCustomizeContent.setup(this, dragController);                                                        

1434                                                                                                                    
1435          // Setup the drag controller (drop targets have to be added in reverse order in priority)                 
1436          dragController.setDragScoller(mWorkspace);                                                                
1437          dragController.setScrollView(mDragLayer);                                                                 
1438          dragController.setMoveTarget(mWorkspace);                                                                 
1439          dragController.addDropTarget(mWorkspace);                                                                 
1440          if (mSearchDropTargetBar != null) {                                                                       
1441              mSearchDropTargetBar.setup(this, dragController);                                                     
1442              mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                    

1443          }                                                                                                         
1444                                                                                                                    
1445          if (getResources().getBoolean(R.bool.debug_memory_enabled)) {                                             
1446              Log.v(TAG, "adding WeightWatcher");                                                                   
1447              mWeightWatcher = new WeightWatcher(this);                                                             
1448              mWeightWatcher.setAlpha(0.5f);                                                                        
1449              ((FrameLayout) mLauncherView).addView(mWeightWatcher,                                                 
1450                      new FrameLayout.LayoutParams(                                                                 
1451                              FrameLayout.LayoutParams.MATCH_PARENT,                                                
1452                              FrameLayout.LayoutParams.WRAP_CONTENT,                                                
1453                              Gravity.BOTTOM)                                                                       
1454              );                                                                                                    
1455                                                                                                                    
1456              boolean show = shouldShowWeightWatcher();                                                             
1457              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
1458          }                                                                                                         
1459      }                                                                                                             
1460                                                                                                                    
1461      /**                                                                                                           
1462       * Sets the all apps button. This method is called from {@link Hotseat}.                                      
1463       */                                                                                                           
1464      public void setAllAppsButton(View allAppsButton) {                                                            
1465          mAllAppsButton = allAppsButton;                                                                           
1466      }                                                                                                             
1467                                                                                                                    
1468      public View getAllAppsButton() {                                                                              
1469          return mAllAppsButton;                                                                                    
1470      }                                                                                                             
1471                                                                                                                    
1472      /**                                                                                                           
1473       * Creates a view representing a shortcut.                                                                    
1474       *                                                                                                            
1475       * @param info The data structure describing the shortcut.                                                    
1476       *                                                                                                            
1477       * @return A View inflated from R.layout.application.                                                         
1478       */                                                                                                           
1479      View createShortcut(ShortcutInfo info) {                                                                      
1480          return createShortcut(R.layout.application,                                                               
1481                  (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);                            
1482      }                                                                                                             
1483                                                                                                                    
1484      /**                                                                                                           
1485       * Creates a view representing a shortcut inflated from the specified resource.                               
1486       *                                                                                                            
1487       * @param layoutResId The id of the XML layout used to create the shortcut.                                   
1488       * @param parent The group the shortcut belongs to.                                                           
1489       * @param info The data structure describing the shortcut.                                                    
1490       *                                                                                                            
1491       * @return A View inflated from layoutResId.                                                                  
1492       */                                                                                                           
1493      public View createShortcut(int layoutResId, ViewGroup parent, ShortcutInfo info) {                            
1494          BubbleTextView favorite = (BubbleTextView) mInflater.inflate(layoutResId, parent, false);                 
1495          favorite.applyFromShortcutInfo(info, mIconCache, true);                                                   
1496          favorite.setOnClickListener(this);                                                                        
1497          favorite.setOnFocusChangeListener(mFocusHandler);                                                         
1498          return favorite;                                                                                          
1499      }                                                                                                             
1500                                                                                                                    
1501      /**                                                                                                           
1502       * Add a shortcut to the workspace.                                                                           
1503       *                                                                                                            
1504       * @param data The intent describing the shortcut.                                                            
1505       * @param cellInfo The position on screen where to create the shortcut.                                       
1506       */                                                                                                           
1507      private void completeAddShortcut(Intent data, long container, long screenId, int cellX,                       
1508              int cellY) {                                                                                          
1509          int[] cellXY = mTmpAddItemCellCoordinates;                                                                
1510          int[] touchXY = mPendingAddInfo.dropPos;                                                                  
1511          CellLayout layout = getCellLayout(container, screenId);                                                   
1512                                                                                                                    
1513          boolean foundCellSpan = false;                                                                            
1514                                                                                                                    
1515          ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);                                            
1516          if (info == null) {                                                                                       
1517              return;                                                                                               
1518          }                                                                                                         
1519          final View view = createShortcut(info);                                                                   
1520                                                                                                                    
1521          // First we check if we already know the exact location where we want to add this item.                   
1522          if (cellX >= 0 && cellY >= 0) {                                                                           
1523              cellXY[0] = cellX;                                                                                    
1524              cellXY[1] = cellY;                                                                                    
1525              foundCellSpan = true;                                                                                 
1526                                                                                                                    
1527              // If appropriate, either create a folder or add to an existing folder                                
1528              if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,                        
1529                      true, null,null)) {                                                                           
1530                  return;                                                                                           
1531              }                                                                                                     
1532              DragObject dragObject = new DragObject();                                                             
1533              dragObject.dragInfo = info;                                                                           
1534              if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,                    
1535                      true)) {                                                                                      
1536                  return;                                                                                           
1537              }                                                                                                     
1538          } else if (touchXY != null) {                                                                             
1539              // when dragging and dropping, just find the closest free spot                                        
1540              int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY);                    
1541              foundCellSpan = (result != null);                                                                     
1542          } else {                                                                                                  
1543              foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);                                                 
1544          }                                                                                                         
1545                                                                                                                    
1546          if (!foundCellSpan) {                                                                                     
1547              showOutOfSpaceMessage(isHotseatLayout(layout));                                                       
1548              return;                                                                                               
1549          }                                                                                                         
1550                                                                                                                    
1551          LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1], false);            

1552                                                                                                                    
1553          if (!mRestoring) {                                                                                        
1554              mWorkspace.addInScreen(view, container, screenId, cellXY[0], cellXY[1], 1, 1,                         
1555                      isWorkspaceLocked());                                                                         
1556          }                                                                                                         
1557      }                                                                                                             
1558                                                                                                                    
1559      static int[] getSpanForWidget(Context context, ComponentName component, int minWidth,                         
1560              int minHeight) {                                                                                      
1561          Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context, component, null);                    
1562          // We want to account for the extra amount of padding that we are adding to the widget                    
1563          // to ensure that it gets the full amount of space that it has requested                                  
1564          int requiredWidth = minWidth + padding.left + padding.right;                                              
1565          int requiredHeight = minHeight + padding.top + padding.bottom;                                            
1566          return CellLayout.rectToCell(requiredWidth, requiredHeight, null);                                        
1567      }                                                                                                             
1568                                                                                                                    
1569      static int[] getSpanForWidget(Context context, AppWidgetProviderInfo info) {                                  
1570          return getSpanForWidget(context, info.provider, info.minWidth, info.minHeight);                           
1571      }                                                                                                             
1572                                                                                                                    
1573      static int[] getMinSpanForWidget(Context context, AppWidgetProviderInfo info) {                               
1574          return getSpanForWidget(context, info.provider, info.minResizeWidth, info.minResizeHeight);               
1575      }                                                                                                             
1576                                                                                                                    
1577      static int[] getSpanForWidget(Context context, PendingAddWidgetInfo info) {                                   
1578          return getSpanForWidget(context, info.componentName, info.minWidth, info.minHeight);                      
1579      }                                                                                                             
1580                                                                                                                    
1581      static int[] getMinSpanForWidget(Context context, PendingAddWidgetInfo info) {                                
1582          return getSpanForWidget(context, info.componentName, info.minResizeWidth,                                 
1583                  info.minResizeHeight);                                                                            
1584      }                                                                                                             
1585                                                                                                                    
1586      /**                                                                                                           
1587       * Add a widget to the workspace.                                                                             
1588       *                                                                                                            
1589       * @param appWidgetId The app widget id                                                                       
1590       */                                                                                                           
1591      private void completeAddAppWidget(int appWidgetId, long container, long screenId,                             

1592              AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {                            
1593                                                                                                                    
1594          ItemInfo info = mPendingAddInfo;                                                                          
1595          if (appWidgetInfo == null) {                                                                              
1596              appWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(this,                                  
1597                      mAppWidgetManager.getAppWidgetInfo(appWidgetId));                                             
1598          }                                                                                                         
1599                                                                                                                    
1600          if (appWidgetInfo.isCustomWidget) {                                                                       
1601              appWidgetId = LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;                                                 
1602          }                                                                                                         
1603                                                                                                                    
1604          LauncherAppWidgetInfo launcherInfo;                                                                       
1605          launcherInfo = new LauncherAppWidgetInfo(appWidgetId, appWidgetInfo.provider);                            
1606          launcherInfo.spanX = info.spanX;                                                                          
1607          launcherInfo.spanY = info.spanY;                                                                          
1608          launcherInfo.minSpanX = info.minSpanX;                                                                    
1609          launcherInfo.minSpanY = info.minSpanY;                                                                    
1610          launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);                                             
1611                                                                                                                    
1612          LauncherModel.addItemToDatabase(this, launcherInfo,                                                       
1613                  container, screenId, info.cellX, info.cellY, false);                                              

1614                                                                                                                    
1615          if (!mRestoring) {                                                                                        
1616              if (hostView == null) {                                                                               
1617                  // Perform actual inflation because we're live                                                    
1618                  launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId,                              
1619                          appWidgetInfo);                                                                           
1620              } else {                                                                                              
1621                  // The AppWidgetHostView has already been inflated and instantiated                               
1622                  launcherInfo.hostView = hostView;                                                                 
1623              }                                                                                                     
1624              launcherInfo.hostView.setTag(launcherInfo);                                                           
1625              launcherInfo.hostView.setVisibility(View.VISIBLE);                                                    
1626              launcherInfo.notifyWidgetSizeChanged(this);                                                           
1627                                                                                                                    
1628              mWorkspace.addInScreen(launcherInfo.hostView, container, screenId, info.cellX,                        
1629                      info.cellY, launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());                     
1630                                                                                                                    
1631              addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);                                 
1632          }                                                                                                         
1633          resetAddInfo();                                                                                           
1634      }                                                                                                             
1635                                                                                                                    
1636      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {                                         
1637          @Override                                                                                                 
1638          public void onReceive(Context context, Intent intent) {                                                   
1639              final String action = intent.getAction();                                                             
1640              if (Intent.ACTION_SCREEN_OFF.equals(action)) {                                                        
1641                  mUserPresent = false;                                                                             
1642                  mDragLayer.clearAllResizeFrames();                                                                
1643                  updateRunning();                                                                                  

1644                                                                                                                    
1645                  // Reset AllApps to its initial state only if we are not in the middle of                         
1646                  // processing a multi-step drop                                                                   
1647                  if (mAppsCustomizeTabHost != null && mPendingAddInfo.container == ItemInfo.NO_ID) {               


1648                      showWorkspace(false);                                                                         
1649                  }                                                                                                 
1650              } else if (Intent.ACTION_USER_PRESENT.equals(action)) {                                               
1651                  mUserPresent = true;                                                                              
1652                  updateRunning();                                                                                  

1653              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {                     
1654                  mModel.resetLoadedState(false, true);                                                             
1655                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1656                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);                                               
1657              } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {                    
1658                  mModel.resetLoadedState(false, true);                                                             
1659                  mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,                                         
1660                          LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE                                                 
1661                                  | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);                                   
1662              } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action)                             
1663                      || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {                        
1664                  getModel().forceReload();                                                                         
1665              }                                                                                                     
1666          }                                                                                                         
1667      };                                                                                                            
1668                                                                                                                    
1669      @Override                                                                                                     
1670      public void onAttachedToWindow() {                                                                            
1671          super.onAttachedToWindow();                                                                               
1672                                                                                                                    
1673          // Listen for broadcasts related to user-presence                                                         
1674          final IntentFilter filter = new IntentFilter();                                                           
1675          filter.addAction(Intent.ACTION_SCREEN_OFF);                                                               
1676          filter.addAction(Intent.ACTION_USER_PRESENT);                                                             
1677          // For handling managed profiles                                                                          
1678          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);                                        
1679          filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);                                      
1680          if (ENABLE_DEBUG_INTENTS) {                                                                               
1681              filter.addAction(DebugIntents.DELETE_DATABASE);                                                       
1682              filter.addAction(DebugIntents.MIGRATE_DATABASE);                                                      
1683          }                                                                                                         
1684          registerReceiver(mReceiver, filter);                                                                      
1685          FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());                              
1686          setupTransparentSystemBarsForLmp();                                                                       
1687          mAttached = true;                                                                                         
1688          mVisible = true;                                                                                          
1689      }                                                                                                             
1690                                                                                                                    
1691      /**                                                                                                           
1692       * Sets up transparent navigation and status bars in LMP.                                                     
1693       * This method is a no-op for other platform versions.                                                        
1694       */                                                                                                           
1695      @TargetApi(19)                                                                                                

1696      private void setupTransparentSystemBarsForLmp() {                                                             
1697          // TODO(sansid): use the APIs directly when compiling against L sdk.                                      
1698          // Currently we use reflection to access the flags and the API to set the transparency                    
1699          // on the System bars.                                                                                    
1700          if (Utilities.isLmpOrAbove()) {                                                                           
1701              try {                                                                                                 
1702                  getWindow().getAttributes().systemUiVisibility |=                                                 
1703                          (View.SYSTEM_UI_FLAG_LAYOUT_STABLE                                                        
1704                                  | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                           
1705                                  | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);                                    
1706                  getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS                         
1707                          | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);                                
1708                  Field drawsSysBackgroundsField = WindowManager.LayoutParams.class.getField(                       
1709                          "FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS");                                                     
1710                  getWindow().addFlags(drawsSysBackgroundsField.getInt(null));                                      
1711                                                                                                                    
1712                  Method setStatusBarColorMethod =                                                                  
1713                          Window.class.getDeclaredMethod("setStatusBarColor", int.class);                           
1714                  Method setNavigationBarColorMethod =                                                              
1715                          Window.class.getDeclaredMethod("setNavigationBarColor", int.class);                       
1716                  setStatusBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                                   
1717                  setNavigationBarColorMethod.invoke(getWindow(), Color.TRANSPARENT);                               
1718              } catch (NoSuchFieldException e) {                                                                    
1719                  Log.w(TAG, "NoSuchFieldException while setting up transparent bars");                             
1720              } catch (NoSuchMethodException ex) {                                                                  
1721                  Log.w(TAG, "NoSuchMethodException while setting up transparent bars");                            
1722              } catch (IllegalAccessException e) {                                                                  
1723                  Log.w(TAG, "IllegalAccessException while setting up transparent bars");                           
1724              } catch (IllegalArgumentException e) {                                                                
1725                  Log.w(TAG, "IllegalArgumentException while setting up transparent bars");                         
1726              } catch (InvocationTargetException e) {                                                               
1727                  Log.w(TAG, "InvocationTargetException while setting up transparent bars");                        
1728              } finally {}                                                                                          










1729          }                                                                                                         
1730      }                                                                                                             
1731                                                                                                                    
1732      @Override                                                                                                     
1733      public void onDetachedFromWindow() {                                                                          
1734          super.onDetachedFromWindow();                                                                             
1735          mVisible = false;                                                                                         
1736                                                                                                                    
1737          if (mAttached) {                                                                                          
1738              unregisterReceiver(mReceiver);                                                                        
1739              mAttached = false;                                                                                    
1740          }                                                                                                         
1741          updateRunning();                                                                                          

1742      }                                                                                                             
1743                                                                                                                    
1744      public void onWindowVisibilityChanged(int visibility) {                                                       
1745          mVisible = visibility == View.VISIBLE;                                                                    
1746          updateRunning();                                                                                          

1747          // The following code used to be in onResume, but it turns out onResume is called when                    
1748          // you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged                    
1749          // is a more appropriate event to handle                                                                  
1750          if (mVisible) {                                                                                           
1751              mAppsCustomizeTabHost.onWindowVisible();                                                              
1752              if (!mWorkspaceLoading) {                                                                             
1753                  final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();                               
1754                  // We want to let Launcher draw itself at least once before we force it to build                  
1755                  // layers on all the workspace pages, so that transitioning to Launcher from other                
1756                  // apps is nice and speedy.                                                                       
1757                  observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {                                
1758                      private boolean mStarted = false;                                                             
1759                      public void onDraw() {                                                                        
1760                          if (mStarted) return;                                                                     
1761                          mStarted = true;                                                                          
1762                          // We delay the layer building a bit in order to give                                     
1763                          // other message processing a time to run.  In particular                                 
1764                          // this avoids a delay in hiding the IME if it was                                        
1765                          // currently shown, because doing that may involve                                        
1766                          // some communication back with the app.                                                  
1767                          mWorkspace.postDelayed(mBuildLayersRunnable, 500);                                        
1768                          final ViewTreeObserver.OnDrawListener listener = this;                                    
1769                          mWorkspace.post(new Runnable() {                                                          
1770                                  public void run() {                                                               
1771                                      if (mWorkspace != null &&                                                     
1772                                              mWorkspace.getViewTreeObserver() != null) {                           
1773                                          mWorkspace.getViewTreeObserver().                                         
1774                                                  removeOnDrawListener(listener);                                   
1775                                      }                                                                             
1776                                  }                                                                                 
1777                              });                                                                                   
1778                          return;                                                                                   
1779                      }                                                                                             
1780                  });                                                                                               
1781              }                                                                                                     
1782              clearTypedText();                                                                                     
1783          }                                                                                                         
1784      }                                                                                                             
1785                                                                                                                    
1786      private void sendAdvanceMessage(long delay) {                                                                 

1787          mHandler.removeMessages(ADVANCE_MSG);                                                                     
1788          Message msg = mHandler.obtainMessage(ADVANCE_MSG);                                                        
1789          mHandler.sendMessageDelayed(msg, delay);                                                                  
1790          mAutoAdvanceSentTime = System.currentTimeMillis();                                                        
1791      }                                                                                                             
1792                                                                                                                    
1793      private void updateRunning() {                                                                                

1794          boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();                    
1795          if (autoAdvanceRunning != mAutoAdvanceRunning) {                                                          
1796              mAutoAdvanceRunning = autoAdvanceRunning;                                                             
1797              if (autoAdvanceRunning) {                                                                             
1798                  long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;                
1799                  sendAdvanceMessage(delay);                                                                        
1800              } else {                                                                                              
1801                  if (!mWidgetsToAdvance.isEmpty()) {                                                               
1802                      mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -                                         
1803                              (System.currentTimeMillis() - mAutoAdvanceSentTime));                                 
1804                  }                                                                                                 
1805                  mHandler.removeMessages(ADVANCE_MSG);                                                             
1806                  mHandler.removeMessages(0); // Remove messages sent using postDelayed()                           
1807              }                                                                                                     
1808          }                                                                                                         
1809      }                                                                                                             
1810                                                                                                                    
1811      private final Handler mHandler = new Handler() {                                                              
1812          @Override                                                                                                 
1813          public void handleMessage(Message msg) {                                                                  
1814              if (msg.what == ADVANCE_MSG) {                                                                        
1815                  int i = 0;                                                                                        
1816                  for (View key: mWidgetsToAdvance.keySet()) {                                                      
1817                      final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);                
1818                      final int delay = mAdvanceStagger * i;                                                        
1819                      if (v instanceof Advanceable) {                                                               
1820                         postDelayed(new Runnable() {                                                               
1821                             public void run() {                                                                    
1822                                 ((Advanceable) v).advance();                                                       
1823                             }                                                                                      
1824                         }, delay);                                                                                 
1825                      }                                                                                             
1826                      i++;                                                                                          
1827                  }                                                                                                 
1828                  sendAdvanceMessage(mAdvanceInterval);                                                             
1829              }                                                                                                     
1830          }                                                                                                         
1831      };                                                                                                            
1832                                                                                                                    
1833      void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {                     
1834          if (appWidgetInfo == null || appWidgetInfo.autoAdvanceViewId == -1) return;                               
1835          View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);                                          
1836          if (v instanceof Advanceable) {                                                                           
1837              mWidgetsToAdvance.put(hostView, appWidgetInfo);                                                       
1838              ((Advanceable) v).fyiWillBeAdvancedByHostKThx();                                                      
1839              updateRunning();                                                                                      

1840          }                                                                                                         
1841      }                                                                                                             
1842                                                                                                                    
1843      void removeWidgetToAutoAdvance(View hostView) {                                                               
1844          if (mWidgetsToAdvance.containsKey(hostView)) {                                                            
1845              mWidgetsToAdvance.remove(hostView);                                                                   
1846              updateRunning();                                                                                      

1847          }                                                                                                         
1848      }                                                                                                             
1849                                                                                                                    
1850      public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {                                             
1851          removeWidgetToAutoAdvance(launcherInfo.hostView);                                                         
1852          launcherInfo.hostView = null;                                                                             
1853      }                                                                                                             
1854                                                                                                                    
1855      void showOutOfSpaceMessage(boolean isHotseatLayout) {                                                         

1856          int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);                    
1857          Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();                                        
1858      }                                                                                                             
1859                                                                                                                    
1860      public ArrayList<AppInfo> getAllAppsList() {                                                                  
1861          return mAppsCustomizeContent.getApps();                                                                   
1862      }                                                                                                             
1863                                                                                                                    
1864      public DragLayer getDragLayer() {                                                                             
1865          return mDragLayer;                                                                                        








1866      }                                                                                                             
1867                                                                                                                    
1868      public Workspace getWorkspace() {                                                                             
1869          return mWorkspace;                                                                                        
1870      }                                                                                                             
1871                                                                                                                    
1872      public Hotseat getHotseat() {                                                                                 
1873          return mHotseat;                                                                                          
1874      }                                                                                                             
1875                                                                                                                    
1876      public ViewGroup getOverviewPanel() {                                                                         
1877          return mOverviewPanel;                                                                                    
1878      }                                                                                                             
1879                                                                                                                    
1880      public SearchDropTargetBar getSearchBar() {                                                                   
1881          return mSearchDropTargetBar;                                                                              
1882      }                                                                                                             
1883                                                                                                                    
1884      public LauncherAppWidgetHost getAppWidgetHost() {                                                             
1885          return mAppWidgetHost;                                                                                    
1886      }                                                                                                             
1887                                                                                                                    
1888      public LauncherModel getModel() {                                                                             
1889          return mModel;                                                                                            
1890      }                                                                                                             
1891                                                                                                                    
1892      protected SharedPreferences getSharedPrefs() {                                                                
1893          return mSharedPrefs;                                                                                      
1894      }                                                                                                             
1895                                                                                                                    
1896      public void closeSystemDialogs() {                                                                            
1897          getWindow().closeAllPanels();                                                                             
1898                                                                                                                    
1899          // Whatever we were doing is hereby canceled.                                                             
1900          setWaitingForResult(false);                                                                               
1901      }                                                                                                             
1902                                                                                                                    
1903      @Override                                                                                                     
1904      protected void onNewIntent(Intent intent) {                                                                   
1905          long startTime = 0;                                                                                       
1906          if (DEBUG_RESUME_TIME) {                                                                                  
1907              startTime = System.currentTimeMillis();                                                               
1908          }                                                                                                         
1909          super.onNewIntent(intent);                                                                                
1910                                                                                                                    
1911          // Close the menu                                                                                         
1912          if (Intent.ACTION_MAIN.equals(intent.getAction())) {                                                      
1913              // also will cancel mWaitingForResult.                                                                
1914              closeSystemDialogs();                                                                                 
1915                                                                                                                    
1916              final boolean alreadyOnHome = mHasFocus && ((intent.getFlags() &                                      
1917                      Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)                                                        
1918                      != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);                                                    
1919                                                                                                                    
1920              if (mWorkspace == null) {                                                                             
1921                  // Can be cases where mWorkspace is null, this prevents a NPE                                     
1922                  return;                                                                                           
1923              }                                                                                                     
1924              Folder openFolder = mWorkspace.getOpenFolder();                                                       
1925              // In all these cases, only animate if we're already on home                                          
1926              mWorkspace.exitWidgetResizeMode();                                                                    
1927                                                                                                                    
1928              boolean moveToDefaultScreen = mLauncherCallbacks != null ?                                            
1929                      mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;                            
1930              if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&                      
1931                      openFolder == null && moveToDefaultScreen) {                                                  
1932                  mWorkspace.moveToDefaultScreen(true);                                                             
1933              }                                                                                                     
1934                                                                                                                    
1935              closeFolder();                                                                                        
1936              exitSpringLoadedDragMode();                                                                           
1937                                                                                                                    
1938              // If we are already on home, then just animate back to the workspace,                                
1939              // otherwise, just wait until onResume to set the state back to Workspace                             
1940              if (alreadyOnHome) {                                                                                  
1941                  showWorkspace(true);                                                                              
1942              } else {                                                                                              
1943                  mOnResumeState = State.WORKSPACE;                                                                 
1944              }                                                                                                     
1945                                                                                                                    
1946              final View v = getWindow().peekDecorView();                                                           
1947              if (v != null && v.getWindowToken() != null) {                                                        
1948                  InputMethodManager imm = (InputMethodManager)getSystemService(                                    
1949                          INPUT_METHOD_SERVICE);                                                                    
1950                  imm.hideSoftInputFromWindow(v.getWindowToken(), 0);                                               
1951              }                                                                                                     
1952                                                                                                                    
1953              // Reset the apps customize page                                                                      
1954              if (!alreadyOnHome && mAppsCustomizeTabHost != null) {                                                
1955                  mAppsCustomizeTabHost.reset();                                                                    








1956              }                                                                                                     
1957                                                                                                                    
1958              if (mLauncherCallbacks != null) {                                                                     
1959                  mLauncherCallbacks.onHomeIntent();                                                                
1960              }                                                                                                     
1961          }                                                                                                         
1962                                                                                                                    
1963          if (DEBUG_RESUME_TIME) {                                                                                  
1964              Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));                 
1965          }                                                                                                         
1966                                                                                                                    
1967          if (mLauncherCallbacks != null) {                                                                         
1968              mLauncherCallbacks.onNewIntent(intent);                                                               
1969          }                                                                                                         
1970      }                                                                                                             
1971                                                                                                                    
1972      @Override                                                                                                     
1973      public void onRestoreInstanceState(Bundle state) {                                                            
1974          super.onRestoreInstanceState(state);                                                                      
1975          for (int page: mSynchronouslyBoundPages) {                                                                
1976              mWorkspace.restoreInstanceStateForChild(page);                                                        
1977          }                                                                                                         
1978      }                                                                                                             
1979                                                                                                                    
1980      @Override                                                                                                     
1981      protected void onSaveInstanceState(Bundle outState) {                                                         
1982          if (mWorkspace.getChildCount() > 0) {                                                                     
1983              outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,                                                         
1984                      mWorkspace.getCurrentPageOffsetFromCustomContent());                                          
1985          }                                                                                                         
1986          super.onSaveInstanceState(outState);                                                                      
1987                                                                                                                    
1988          outState.putInt(RUNTIME_STATE, mState.ordinal());                                                         
1989          // We close any open folder since it will not be re-opened, and we need to make sure                      
1990          // this state is reflected.                                                                               
1991          closeFolder();                                                                                            
1992                                                                                                                    
1993          if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&                       
1994                  mWaitingForResult) {                                                                              
1995              outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container);                     
1996              outState.putLong(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screenId);                         
1997              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX);                             
1998              outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY);                             
1999              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);                             
2000              outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);                             
2001              outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);                 
2002              outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);                            
2003          }                                                                                                         
2004                                                                                                                    
2005          if (mFolderInfo != null && mWaitingForResult) {                                                           
2006              outState.putBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, true);                                       
2007              outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);                             
2008          }                                                                                                         
2009                                                                                                                    
2010          // Save the current AppsCustomize tab                                                                     
2011          if (mAppsCustomizeTabHost != null) {                                                                      
2012              AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();                     
2013              String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);                           
2014              if (currentTabTag != null) {                                                                          
2015                  outState.putString("apps_customize_currentTab", currentTabTag);                                   
2016              }                                                                                                     
2017              int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();                                 
2018              outState.putInt("apps_customize_currentIndex", currentIndex);                                         
2019          }                                                                                                         


2020          outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);                                        
2021                                                                                                                    
2022          if (mLauncherCallbacks != null) {                                                                         
2023              mLauncherCallbacks.onSaveInstanceState(outState);                                                     
2024          }                                                                                                         
2025      }                                                                                                             
2026                                                                                                                    
2027      @Override                                                                                                     
2028      public void onDestroy() {                                                                                     
2029          super.onDestroy();                                                                                        
2030                                                                                                                    
2031          // Remove all pending runnables                                                                           
2032          mHandler.removeMessages(ADVANCE_MSG);                                                                     
2033          mHandler.removeMessages(0);                                                                               
2034          mWorkspace.removeCallbacks(mBuildLayersRunnable);                                                         
2035                                                                                                                    
2036          // Stop callbacks from LauncherModel                                                                      
2037          LauncherAppState app = (LauncherAppState.getInstance());                                                  
2038                                                                                                                    
2039          // It's possible to receive onDestroy after a new Launcher activity has                                   
2040          // been created. In this case, don't interfere with the new Launcher.                                     
2041          if (mModel.isCurrentCallbacks(this)) {                                                                    
2042              mModel.stopLoader();                                                                                  
2043              app.setLauncher(null);                                                                                
2044          }                                                                                                         
2045                                                                                                                    
2046          try {                                                                                                     
2047              mAppWidgetHost.stopListening();                                                                       
2048          } catch (NullPointerException ex) {                                                                       
2049              Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);                   
2050          }                                                                                                         
2051          mAppWidgetHost = null;                                                                                    
2052                                                                                                                    
2053          mWidgetsToAdvance.clear();                                                                                
2054                                                                                                                    
2055          TextKeyListener.getInstance().release();                                                                  
2056                                                                                                                    
2057          // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace               
2058          // to prevent leaking Launcher activities on orientation change.                                          
2059          if (mModel != null) {                                                                                     
2060              mModel.unbindItemInfosAndClearQueuedBindRunnables();                                                  
2061          }                                                                                                         
2062                                                                                                                    
2063          getContentResolver().unregisterContentObserver(mWidgetObserver);                                          
2064          unregisterReceiver(mCloseSystemDialogsReceiver);                                                          
2065                                                                                                                    
2066          mDragLayer.clearAllResizeFrames();                                                                        
2067          ((ViewGroup) mWorkspace.getParent()).removeAllViews();                                                    
2068          mWorkspace.removeAllWorkspaceScreens();                                                                   
2069          mWorkspace = null;                                                                                        
2070          mDragController = null;                                                                                   
2071                                                                                                                    
2072          LauncherAnimUtils.onDestroyActivity();                                                                    
2073                                                                                                                    
2074          if (mLauncherCallbacks != null) {                                                                         
2075              mLauncherCallbacks.onDestroy();                                                                       
2076          }                                                                                                         
2077      }                                                                                                             
2078                                                                                                                    
2079      public DragController getDragController() {                                                                   
2080          return mDragController;                                                                                   
2081      }                                                                                                             
2082                                                                                                                    
2083      @Override                                                                                                     
2084      public void startActivityForResult(Intent intent, int requestCode) {                                          
2085          onStartForResult(requestCode);                                                                            
2086          super.startActivityForResult(intent, requestCode);                                                        
2087      }                                                                                                             
2088                                                                                                                    
2089      @Override                                                                                                     
2090      public void startIntentSenderForResult (IntentSender intent, int requestCode,                                 
2091              Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {                
2092          onStartForResult(requestCode);                                                                            
2093          try {                                                                                                     
2094              super.startIntentSenderForResult(intent, requestCode,                                                 
2095                  fillInIntent, flagsMask, flagsValues, extraFlags, options);                                       
2096          } catch (IntentSender.SendIntentException e) {                                                            
2097              throw new ActivityNotFoundException();                                                                
2098          }                                                                                                         
2099      }                                                                                                             
2100                                                                                                                    
2101      private void onStartForResult(int requestCode) {                                                              
2102          if (requestCode >= 0) {                                                                                   
2103              setWaitingForResult(true);                                                                            
2104          }                                                                                                         
2105      }                                                                                                             
2106                                                                                                                    
2107      /**                                                                                                           
2108       * Indicates that we want global search for this activity by setting the globalSearch                         
2109       * argument for {@link #startSearch} to true.                                                                 
2110       */                                                                                                           
2111      @Override                                                                                                     
2112      public void startSearch(String initialQuery, boolean selectInitialQuery,                                      
2113              Bundle appSearchData, boolean globalSearch) {                                                         
2114                                                                                                                    
2115          showWorkspace(true);                                                                                      
2116                                                                                                                    
2117          if (initialQuery == null) {                                                                               
2118              // Use any text typed in the launcher as the initial query                                            
2119              initialQuery = getTypedText();                                                                        
2120          }                                                                                                         
2121          if (appSearchData == null) {                                                                              
2122              appSearchData = new Bundle();                                                                         
2123              appSearchData.putString("source", "launcher-search");                                                 
2124          }                                                                                                         
2125          Rect sourceBounds = new Rect();                                                                           
2126          if (mSearchDropTargetBar != null) {                                                                       
2127              sourceBounds = mSearchDropTargetBar.getSearchBarBounds();                                             
2128          }                                                                                                         
2129                                                                                                                    
2130          boolean clearTextImmediately = startSearch(initialQuery, selectInitialQuery,                              
2131                  appSearchData, sourceBounds);                                                                     
2132          if (clearTextImmediately) {                                                                               
2133              clearTypedText();                                                                                     
2134          }                                                                                                         
2135      }                                                                                                             
2136                                                                                                                    
2137      /**                                                                                                           
2138       * Start a text search.                                                                                       
2139       *                                                                                                            
2140       * @return {@code true} if the search will start immediately, so any further keypresses                       
2141       * will be handled directly by the search UI. {@code false} if {@link Launcher} should continue               
2142       * to buffer keypresses.                                                                                      
2143       */                                                                                                           
2144      public boolean startSearch(String initialQuery,                                                               
2145              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2146          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
2147              return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,                
2148                      sourceBounds);                                                                                
2149          }                                                                                                         
2150                                                                                                                    
2151          startGlobalSearch(initialQuery, selectInitialQuery,                                                       
2152                  appSearchData, sourceBounds);                                                                     
2153          return false;                                                                                             
2154      }                                                                                                             
2155                                                                                                                    
2156      /**                                                                                                           
2157       * Starts the global search activity. This code is a copied from SearchManager                                
2158       */                                                                                                           
2159      private void startGlobalSearch(String initialQuery,                                                           
2160              boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {                                
2161          final SearchManager searchManager =                                                                       
2162              (SearchManager) getSystemService(Context.SEARCH_SERVICE);                                             
2163          ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();                             
2164          if (globalSearchActivity == null) {                                                                       
2165              Log.w(TAG, "No global search activity found.");                                                       
2166              return;                                                                                               
2167          }                                                                                                         
2168          Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);                                    
2169          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2170          intent.setComponent(globalSearchActivity);                                                                
2171          // Make sure that we have a Bundle to put source in                                                       
2172          if (appSearchData == null) {                                                                              
2173              appSearchData = new Bundle();                                                                         
2174          } else {                                                                                                  
2175              appSearchData = new Bundle(appSearchData);                                                            
2176          }                                                                                                         
2177          // Set source to package name of app that starts global search if not set already.                        
2178          if (!appSearchData.containsKey("source")) {                                                               
2179              appSearchData.putString("source", getPackageName());                                                  
2180          }                                                                                                         
2181          intent.putExtra(SearchManager.APP_DATA, appSearchData);                                                   
2182          if (!TextUtils.isEmpty(initialQuery)) {                                                                   
2183              intent.putExtra(SearchManager.QUERY, initialQuery);                                                   
2184          }                                                                                                         
2185          if (selectInitialQuery) {                                                                                 
2186              intent.putExtra(SearchManager.EXTRA_SELECT_QUERY, selectInitialQuery);                                
2187          }                                                                                                         
2188          intent.setSourceBounds(sourceBounds);                                                                     
2189          try {                                                                                                     
2190              startActivity(intent);                                                                                
2191          } catch (ActivityNotFoundException ex) {                                                                  
2192              Log.e(TAG, "Global search activity not found: " + globalSearchActivity);                              
2193          }                                                                                                         
2194      }                                                                                                             
2195                                                                                                                    
2196      public boolean isOnCustomContent() {                                                                          
2197          return mWorkspace.isOnOrMovingToCustomContent();                                                          
2198      }                                                                                                             
2199                                                                                                                    
2200      @Override                                                                                                     
2201      public boolean onPrepareOptionsMenu(Menu menu) {                                                              
2202          super.onPrepareOptionsMenu(menu);                                                                         
2203          if (!isOnCustomContent()) {                                                                               
2204              // Close any open folders                                                                             
2205              closeFolder();                                                                                        
2206              // Stop resizing any widgets                                                                          
2207              mWorkspace.exitWidgetResizeMode();                                                                    
2208              if (!mWorkspace.isInOverviewMode()) {                                                                 
2209                  // Show the overview mode                                                                         
2210                  showOverviewMode(true);                                                                           
2211              } else {                                                                                              
2212                  showWorkspace(true);                                                                              
2213              }                                                                                                     
2214          }                                                                                                         
2215          if (mLauncherCallbacks != null) {                                                                         
2216              return mLauncherCallbacks.onPrepareOptionsMenu(menu);                                                 
2217          }                                                                                                         
2218                                                                                                                    
2219          return false;                                                                                             
2220      }                                                                                                             
2221                                                                                                                    
2222      @Override                                                                                                     
2223      public boolean onSearchRequested() {                                                                          
2224          startSearch(null, false, null, true);                                                                     
2225          // Use a custom animation for launching search                                                            
2226          return true;                                                                                              
2227      }                                                                                                             
2228                                                                                                                    
2229      public boolean isWorkspaceLocked() {                                                                          
2230          return mWorkspaceLoading || mWaitingForResult;                                                            
2231      }                                                                                                             
2232                                                                                                                    
2233      public boolean isWorkspaceLoading() {                                                                         
2234          return mWorkspaceLoading;                                                                                 
2235      }                                                                                                             
2236                                                                                                                    
2237      private void setWorkspaceLoading(boolean value) {                                                             
2238          boolean isLocked = isWorkspaceLocked();                                                                   
2239          mWorkspaceLoading = value;                                                                                
2240          if (isLocked != isWorkspaceLocked()) {                                                                    
2241              onWorkspaceLockedChanged();                                                                           
2242          }                                                                                                         
2243      }                                                                                                             
2244                                                                                                                    
2245      private void setWaitingForResult(boolean value) {                                                             
2246          boolean isLocked = isWorkspaceLocked();                                                                   
2247          mWaitingForResult = value;                                                                                
2248          if (isLocked != isWorkspaceLocked()) {                                                                    
2249              onWorkspaceLockedChanged();                                                                           
2250          }                                                                                                         
2251      }                                                                                                             
2252                                                                                                                    
2253      protected void onWorkspaceLockedChanged() {                                                                   
2254          if (mLauncherCallbacks != null) {                                                                         
2255              mLauncherCallbacks.onWorkspaceLockedChanged();                                                        
2256          }                                                                                                         
2257      }                                                                                                             
2258                                                                                                                    
2259      private void resetAddInfo() {                                                                                 
2260          mPendingAddInfo.container = ItemInfo.NO_ID;                                                               
2261          mPendingAddInfo.screenId = -1;                                                                            
2262          mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1;                                                       
2263          mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1;                                                       
2264          mPendingAddInfo.minSpanX = mPendingAddInfo.minSpanY = -1;                                                 
2265          mPendingAddInfo.dropPos = null;                                                                           
2266      }                                                                                                             
2267                                                                                                                    
2268      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info, final                                       
2269              AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo) {                   
2270          addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);                                       
2271      }                                                                                                             
2272                                                                                                                    
2273      void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,                                             
2274              final AppWidgetHostView boundWidget, final LauncherAppWidgetProviderInfo appWidgetInfo,               
2275              int delay) {                                                                                          
2276          if (appWidgetInfo.configure != null) {                                                                    
2277              mPendingAddWidgetInfo = appWidgetInfo;                                                                
2278              mPendingAddWidgetId = appWidgetId;                                                                    
2279                                                                                                                    
2280              // Launch over to configure widget, if needed                                                         
2281              mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,                               
2282                      mAppWidgetHost, REQUEST_CREATE_APPWIDGET);                                                    
2283                                                                                                                    
2284          } else {                                                                                                  
2285              // Otherwise just add it                                                                              
2286              Runnable onComplete = new Runnable() {                                                                
2287                  @Override                                                                                         
2288                  public void run() {                                                                               
2289                      // Exit spring loaded mode if necessary after adding the widget                               
2290                      exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,                   
2291                              null);                                                                                
2292                  }                                                                                                 
2293              };                                                                                                    
2294              completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,                         
2295                      appWidgetInfo);                                                                               
2296              mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);                             
2297          }                                                                                                         
2298      }                                                                                                             
2299                                                                                                                    
2300      protected void moveToCustomContentScreen(boolean animate) {                                                   
2301          // Close any folders that may be open.                                                                    
2302          closeFolder();                                                                                            
2303          mWorkspace.moveToCustomContentScreen(animate);                                                            
2304      }                                                                                                             
2305                                                                                                                    
2306      public void addPendingItem(PendingAddItemInfo info, long container, long screenId,                            
2307              int[] cell, int spanX, int spanY) {                                                                   
2308          switch (info.itemType) {                                                                                  
2309              case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:                                           
2310              case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:                                                  
2311                  int span[] = new int[2];                                                                          
2312                  span[0] = spanX;                                                                                  
2313                  span[1] = spanY;                                                                                  
2314                  addAppWidgetFromDrop((PendingAddWidgetInfo) info,                                                 
2315                          container, screenId, cell, span);                                                         
2316                  break;                                                                                            
2317              case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                                   
2318                  processShortcutFromDrop(info.componentName, container, screenId, cell);                           
2319                  break;                                                                                            
2320              default:                                                                                              
2321                  throw new IllegalStateException("Unknown item type: " + info.itemType);                           
2322              }                                                                                                     
2323      }                                                                                                             
2324                                                                                                                    
2325      /**                                                                                                           
2326       * Process a shortcut drop.                                                                                   
2327       *                                                                                                            
2328       * @param componentName The name of the component                                                             
2329       * @param screenId The ID of the screen where it should be added                                              
2330       * @param cell The cell it should be added to, optional                                                       
2331       */                                                                                                           
2332      private void processShortcutFromDrop(ComponentName componentName, long container, long screenId,              
2333              int[] cell) {                                                                                         
2334          resetAddInfo();                                                                                           
2335          mPendingAddInfo.container = container;                                                                    
2336          mPendingAddInfo.screenId = screenId;                                                                      
2337          mPendingAddInfo.dropPos = null;                                                                           
2338                                                                                                                    
2339          if (cell != null) {                                                                                       
2340              mPendingAddInfo.cellX = cell[0];                                                                      
2341              mPendingAddInfo.cellY = cell[1];                                                                      
2342          }                                                                                                         
2343                                                                                                                    
2344          Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);                                  
2345          createShortcutIntent.setComponent(componentName);                                                         
2346          processShortcut(createShortcutIntent);                                                                    
2347      }                                                                                                             
2348                                                                                                                    
2349      /**                                                                                                           
2350       * Process a widget drop.                                                                                     
2351       *                                                                                                            
2352       * @param info The PendingAppWidgetInfo of the widget being added.                                            
2353       * @param screenId The ID of the screen where it should be added                                              
2354       * @param cell The cell it should be added to, optional                                                       
2355       */                                                                                                           
2356      private void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, long screenId,                   
2357              int[] cell, int[] span) {                                                                             
2358          resetAddInfo();                                                                                           
2359          mPendingAddInfo.container = info.container = container;                                                   
2360          mPendingAddInfo.screenId = info.screenId = screenId;                                                      
2361          mPendingAddInfo.dropPos = null;                                                                           
2362          mPendingAddInfo.minSpanX = info.minSpanX;                                                                 
2363          mPendingAddInfo.minSpanY = info.minSpanY;                                                                 
2364                                                                                                                    
2365          if (cell != null) {                                                                                       
2366              mPendingAddInfo.cellX = cell[0];                                                                      
2367              mPendingAddInfo.cellY = cell[1];                                                                      
2368          }                                                                                                         
2369          if (span != null) {                                                                                       
2370              mPendingAddInfo.spanX = span[0];                                                                      
2371              mPendingAddInfo.spanY = span[1];                                                                      
2372          }                                                                                                         
2373                                                                                                                    
2374          AppWidgetHostView hostView = info.boundWidget;                                                            
2375          int appWidgetId;                                                                                          
2376          if (hostView != null) {                                                                                   
2377              appWidgetId = hostView.getAppWidgetId();                                                              
2378              addAppWidgetImpl(appWidgetId, info, hostView, info.info);                                             
2379          } else {                                                                                                  
2380              // In this case, we either need to start an activity to get permission to bind                        
2381              // the widget, or we need to start an activity to configure the widget, or both.                      
2382              appWidgetId = getAppWidgetHost().allocateAppWidgetId();                                               
2383              Bundle options = info.bindOptions;                                                                    
2384                                                                                                                    
2385              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
2386                      appWidgetId, info.info, options);                                                             
2387              if (success) {                                                                                        
2388                  addAppWidgetImpl(appWidgetId, info, null, info.info);                                             
2389              } else {                                                                                              
2390                  mPendingAddWidgetInfo = info.info;                                                                
2391                  Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);                               
2392                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);                                
2393                  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);                   
2394                  mAppWidgetManager.getUser(mPendingAddWidgetInfo)                                                  
2395                      .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);                      
2396                  // TODO: we need to make sure that this accounts for the options bundle.                          
2397                  // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);                            
2398                  startActivityForResult(intent, REQUEST_BIND_APPWIDGET);                                           
2399              }                                                                                                     
2400          }                                                                                                         
2401      }                                                                                                             
2402                                                                                                                    
2403      void processShortcut(Intent intent) {                                                                         
2404          Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_SHORTCUT);                            
2405      }                                                                                                             
2406                                                                                                                    
2407      void processWallpaper(Intent intent) {                                                                        
2408          startActivityForResult(intent, REQUEST_PICK_WALLPAPER);                                                   
2409      }                                                                                                             
2410                                                                                                                    
2411      FolderIcon addFolder(CellLayout layout, long container, final long screenId, int cellX,                       
2412              int cellY) {                                                                                          
2413          final FolderInfo folderInfo = new FolderInfo();                                                           
2414          folderInfo.title = getText(R.string.folder_name);                                                         
2415                                                                                                                    
2416          // Update the model                                                                                       
2417          LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId, cellX, cellY,             
2418                  false);                                                                                           


2419          sFolders.put(folderInfo.id, folderInfo);                                                                  
2420                                                                                                                    
2421          // Create the view                                                                                        
2422          FolderIcon newFolder =                                                                                    
2423              FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache);                       
2424          mWorkspace.addInScreen(newFolder, container, screenId, cellX, cellY, 1, 1,                                
2425                  isWorkspaceLocked());                                                                             
2426          // Force measure the new folder icon                                                                      
2427          CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder);                                     
2428          parent.getShortcutsAndWidgets().measureChild(newFolder);                                                  
2429          return newFolder;                                                                                         
2430      }                                                                                                             
2431                                                                                                                    
2432      void removeFolder(FolderInfo folder) {                                                                        
2433          sFolders.remove(folder.id);                                                                               
2434      }                                                                                                             
2435                                                                                                                    
2436      protected ComponentName getWallpaperPickerComponent() {                                                       
2437          if (mLauncherCallbacks != null) {                                                                         
2438              return mLauncherCallbacks.getWallpaperPickerComponent();                                              
2439          }                                                                                                         
2440          return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());              
2441      }                                                                                                             
2442                                                                                                                    
2443      /**                                                                                                           
2444       * Registers various content observers. The current implementation registers                                  
2445       * only a favorites observer to keep track of the favorites applications.                                     
2446       */                                                                                                           
2447      private void registerContentObservers() {                                                                     
2448          ContentResolver resolver = getContentResolver();                                                          
2449          resolver.registerContentObserver(LauncherProvider.CONTENT_APPWIDGET_RESET_URI,                            
2450                  true, mWidgetObserver);                                                                           
2451      }                                                                                                             
2452                                                                                                                    
2453      @Override                                                                                                     
2454      public boolean dispatchKeyEvent(KeyEvent event) {                                                             
2455          if (event.getAction() == KeyEvent.ACTION_DOWN) {                                                          
2456              switch (event.getKeyCode()) {                                                                         
2457                  case KeyEvent.KEYCODE_HOME:                                                                       
2458                      return true;                                                                                  
2459                  case KeyEvent.KEYCODE_VOLUME_DOWN:                                                                
2460                      if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {                                       
2461                          dumpState();                                                                              
2462                          return true;                                                                              
2463                      }                                                                                             
2464                      break;                                                                                        
2465              }                                                                                                     
2466          } else if (event.getAction() == KeyEvent.ACTION_UP) {                                                     
2467              switch (event.getKeyCode()) {                                                                         
2468                  case KeyEvent.KEYCODE_HOME:                                                                       
2469                      return true;                                                                                  
2470              }                                                                                                     
2471          }                                                                                                         
2472                                                                                                                    
2473          return super.dispatchKeyEvent(event);                                                                     
2474      }                                                                                                             
2475                                                                                                                    
2476      @Override                                                                                                     
2477      public void onBackPressed() {                                                                                 
2478          if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {                               
2479              return;                                                                                               
2480          }                                                                                                         
2481                                                                                                                    
2482          if (isAllAppsVisible()) {                                                                                 
2483              if (mAppsCustomizeContent.getContentType() ==                                                         
2484                      AppsCustomizePagedView.ContentType.Applications) {                                            
2485                  showWorkspace(true);                                                                              
2486              } else {                                                                                              
2487                  showOverviewMode(true);                                                                           
2488              }                                                                                                     










2489          } else if (mWorkspace.isInOverviewMode()) {                                                               
2490              mWorkspace.exitOverviewMode(true);                                                                    
2491          } else if (mWorkspace.getOpenFolder() != null) {                                                          
2492              Folder openFolder = mWorkspace.getOpenFolder();                                                       
2493              if (openFolder.isEditingName()) {                                                                     
2494                  openFolder.dismissEditingName();                                                                  
2495              } else {                                                                                              
2496                  closeFolder();                                                                                    
2497              }                                                                                                     
2498          } else {                                                                                                  
2499              mWorkspace.exitWidgetResizeMode();                                                                    
2500                                                                                                                    
2501              // Back button is a no-op here, but give at least some feedback for the button press                  
2502              mWorkspace.showOutlinesTemporarily();                                                                 
2503          }                                                                                                         
2504      }                                                                                                             
2505                                                                                                                    
2506      /**                                                                                                           
2507       * Re-listen when widgets are reset.                                                                          
2508       */                                                                                                           
2509      private void onAppWidgetReset() {                                                                             

2510          if (mAppWidgetHost != null) {                                                                             
2511              mAppWidgetHost.startListening();                                                                      
2512          }                                                                                                         
2513      }                                                                                                             
2514                                                                                                                    
2515      /**                                                                                                           
2516       * Launches the intent referred by the clicked shortcut.                                                      
2517       *                                                                                                            
2518       * @param v The view representing the clicked shortcut.                                                       
2519       */                                                                                                           
2520      public void onClick(View v) {                                                                                 
2521          // Make sure that rogue clicks don't get through while allapps is launching, or after the                 
2522          // view has detached (it's possible for this to happen if the view is removed mid touch).                 
2523          if (v.getWindowToken() == null) {                                                                         
2524              return;                                                                                               
2525          }                                                                                                         
2526                                                                                                                    
2527          if (!mWorkspace.isFinishedSwitchingState()) {                                                             
2528              return;                                                                                               
2529          }                                                                                                         
2530                                                                                                                    
2531          if (v instanceof Workspace) {                                                                             
2532              if (mWorkspace.isInOverviewMode()) {                                                                  
2533                  mWorkspace.exitOverviewMode(true);                                                                
2534              }                                                                                                     
2535              return;                                                                                               
2536          }                                                                                                         
2537                                                                                                                    
2538          if (v instanceof CellLayout) {                                                                            
2539              if (mWorkspace.isInOverviewMode()) {                                                                  
2540                  mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);                                    
2541              }                                                                                                     
2542          }                                                                                                         
2543                                                                                                                    
2544          Object tag = v.getTag();                                                                                  
2545          if (tag instanceof ShortcutInfo) {                                                                        
2546              onClickAppShortcut(v);                                                                                
2547          } else if (tag instanceof FolderInfo) {                                                                   
2548              if (v instanceof FolderIcon) {                                                                        
2549                  onClickFolderIcon(v);                                                                             
2550              }                                                                                                     
2551          } else if (v == mAllAppsButton) {                                                                         
2552              onClickAllAppsButton(v);                                                                              
2553          } else if (tag instanceof AppInfo) {                                                                      
2554              startAppShortcutOrInfoActivity(v);                                                                    
2555          } else if (tag instanceof LauncherAppWidgetInfo) {                                                        
2556              if (v instanceof PendingAppWidgetHostView) {                                                          
2557                  onClickPendingWidget((PendingAppWidgetHostView) v);                                               
2558              }                                                                                                     
2559          }                                                                                                         
2560      }                                                                                                             
2561                                                                                                                    
2562      public void onClickPagedViewIcon(View v) {                                                                    
2563          startAppShortcutOrInfoActivity(v);                                                                        
2564          if (mLauncherCallbacks != null) {                                                                         
2565              mLauncherCallbacks.onClickPagedViewIcon(v);                                                           
2566          }                                                                                                         
2567      }                                                                                                             
2568                                                                                                                    
2569      public boolean onTouch(View v, MotionEvent event) {                                                           
2570          return false;                                                                                             
2571      }                                                                                                             
2572                                                                                                                    
2573      /**                                                                                                           
2574       * Event handler for the app widget view which has not fully restored.                                        
2575       */                                                                                                           
2576      public void onClickPendingWidget(final PendingAppWidgetHostView v) {                                          
2577          if (mIsSafeModeEnabled) {                                                                                 
2578              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2579              return;                                                                                               
2580          }                                                                                                         
2581                                                                                                                    
2582          final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();                                    
2583          if (v.isReadyForClickSetup()) {                                                                           
2584              int widgetId = info.appWidgetId;                                                                      
2585              AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                   
2586              if (appWidgetInfo != null) {                                                                          
2587                  mPendingAddWidgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(                           
2588                          this, appWidgetInfo);                                                                     
2589                  mPendingAddInfo.copyFrom(info);                                                                   
2590                  mPendingAddWidgetId = widgetId;                                                                   
2591                                                                                                                    
2592                  AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,                       
2593                          info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);                   
2594              }                                                                                                     
2595          } else if (info.installProgress < 0) {                                                                    
2596              // The install has not been queued                                                                    
2597              final String packageName = info.providerName.getPackageName();                                        
2598              showBrokenAppInstallDialog(packageName,                                                               
2599                  new DialogInterface.OnClickListener() {                                                           
2600                      public void onClick(DialogInterface dialog, int id) {                                         
2601                          startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                 
2602                      }                                                                                             
2603                  });                                                                                               
2604          } else {                                                                                                  
2605              // Download has started.                                                                              
2606              final String packageName = info.providerName.getPackageName();                                        
2607              startActivitySafely(v, LauncherModel.getMarketIntent(packageName), info);                             
2608          }                                                                                                         
2609      }                                                                                                             
2610                                                                                                                    
2611      /**                                                                                                           
2612       * Event handler for the "grid" button that appears on the home screen, which                                 
2613       * enters all apps mode.                                                                                      
2614       *                                                                                                            
2615       * @param v The view that was clicked.                                                                        
2616       */                                                                                                           
2617      protected void onClickAllAppsButton(View v) {                                                                 
2618          if (LOGD) Log.d(TAG, "onClickAllAppsButton");                                                             
2619          if (isAllAppsVisible()) {                                                                                 

2620              showWorkspace(true);                                                                                  
2621          } else {                                                                                                  
2622              showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);                            
2623          }                                                                                                         
2624          if (mLauncherCallbacks != null) {                                                                         
2625              mLauncherCallbacks.onClickAllAppsButton(v);                                                           

2626          }                                                                                                         
2627      }                                                                                                             
2628                                                                                                                    
2629      private void showBrokenAppInstallDialog(final String packageName,                                             
2630              DialogInterface.OnClickListener onSearchClickListener) {                                              
2631          new AlertDialog.Builder(this)                                                                             
2632              .setTitle(R.string.abandoned_promises_title)                                                          
2633              .setMessage(R.string.abandoned_promise_explanation)                                                   
2634              .setPositiveButton(R.string.abandoned_search, onSearchClickListener)                                  
2635              .setNeutralButton(R.string.abandoned_clean_this,                                                      
2636                  new DialogInterface.OnClickListener() {                                                           
2637                      public void onClick(DialogInterface dialog, int id) {                                         
2638                          final UserHandleCompat user = UserHandleCompat.myUserHandle();                            
2639                          mWorkspace.removeAbandonedPromise(packageName, user);                                     
2640                      }                                                                                             
2641                  })                                                                                                
2642              .create().show();                                                                                     
2643          return;                                                                                                   
2644      }                                                                                                             
2645                                                                                                                    
2646      /**                                                                                                           
2647       * Event handler for an app shortcut click.                                                                   
2648       *                                                                                                            
2649       * @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.                          
2650       */                                                                                                           
2651      protected void onClickAppShortcut(final View v) {                                                             
2652          if (LOGD) Log.d(TAG, "onClickAppShortcut");                                                               
2653          Object tag = v.getTag();                                                                                  
2654          if (!(tag instanceof ShortcutInfo)) {                                                                     
2655              throw new IllegalArgumentException("Input must be a Shortcut");                                       
2656          }                                                                                                         
2657                                                                                                                    
2658          // Open shortcut                                                                                          
2659          final ShortcutInfo shortcut = (ShortcutInfo) tag;                                                         
2660                                                                                                                    
2661          if (shortcut.isDisabled != 0) {                                                                           
2662              int error = R.string.activity_not_available;                                                          
2663              if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {                               
2664                  error = R.string.safemode_shortcut_error;                                                         
2665              }                                                                                                     
2666              Toast.makeText(this, error, Toast.LENGTH_SHORT).show();                                               
2667              return;                                                                                               
2668          }                                                                                                         
2669                                                                                                                    
2670          final Intent intent = shortcut.intent;                                                                    
2671                                                                                                                    
2672          // Check for special shortcuts                                                                            
2673          if (intent.getComponent() != null) {                                                                      
2674              final String shortcutClass = intent.getComponent().getClassName();                                    
2675                                                                                                                    
2676              if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {                                       
2677                  MemoryDumpActivity.startDump(this);                                                               
2678                  return;                                                                                           
2679              } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {                               
2680                  toggleShowWeightWatcher();                                                                        
2681                  return;                                                                                           
2682              }                                                                                                     
2683          }                                                                                                         
2684                                                                                                                    
2685          // Check for abandoned promise                                                                            
2686          if ((v instanceof BubbleTextView)                                                                         
2687                  && shortcut.isPromise()                                                                           
2688                  && !shortcut.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE)) {                           
2689              showBrokenAppInstallDialog(                                                                           
2690                      shortcut.getTargetComponent().getPackageName(),                                               
2691                      new DialogInterface.OnClickListener() {                                                       
2692                          public void onClick(DialogInterface dialog, int id) {                                     
2693                              startAppShortcutOrInfoActivity(v);                                                    
2694                          }                                                                                         
2695                      });                                                                                           
2696              return;                                                                                               
2697          }                                                                                                         
2698                                                                                                                    
2699          // Start activities                                                                                       
2700          startAppShortcutOrInfoActivity(v);                                                                        
2701                                                                                                                    
2702          if (mLauncherCallbacks != null) {                                                                         
2703              mLauncherCallbacks.onClickAppShortcut(v);                                                             
2704          }                                                                                                         
2705      }                                                                                                             
2706                                                                                                                    
2707      private void startAppShortcutOrInfoActivity(View v) {                                                         

2708          Object tag = v.getTag();                                                                                  
2709          final ShortcutInfo shortcut;                                                                              
2710          final Intent intent;                                                                                      
2711          if (tag instanceof ShortcutInfo) {                                                                        
2712              shortcut = (ShortcutInfo) tag;                                                                        
2713              intent = shortcut.intent;                                                                             
2714              int[] pos = new int[2];                                                                               
2715              v.getLocationOnScreen(pos);                                                                           
2716              intent.setSourceBounds(new Rect(pos[0], pos[1],                                                       
2717                      pos[0] + v.getWidth(), pos[1] + v.getHeight()));                                              
2718                                                                                                                    
2719          } else if (tag instanceof AppInfo) {                                                                      
2720              shortcut = null;                                                                                      
2721              intent = ((AppInfo) tag).intent;                                                                      
2722          } else {                                                                                                  
2723              throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");                            
2724          }                                                                                                         
2725                                                                                                                    
2726          boolean success = startActivitySafely(v, intent, tag);                                                    
2727          mStats.recordLaunch(intent, shortcut);                                                                    
2728                                                                                                                    
2729          if (success && v instanceof BubbleTextView) {                                                             
2730              mWaitingForResume = (BubbleTextView) v;                                                               
2731              mWaitingForResume.setStayPressed(true);                                                               
2732          }                                                                                                         
2733      }                                                                                                             
2734                                                                                                                    
2735      /**                                                                                                           
2736       * Event handler for a folder icon click.                                                                     
2737       *                                                                                                            
2738       * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.                             
2739       */                                                                                                           
2740      protected void onClickFolderIcon(View v) {                                                                    
2741          if (LOGD) Log.d(TAG, "onClickFolder");                                                                    
2742          if (!(v instanceof FolderIcon)){                                                                          
2743              throw new IllegalArgumentException("Input must be a FolderIcon");                                     
2744          }                                                                                                         
2745                                                                                                                    
2746          FolderIcon folderIcon = (FolderIcon) v;                                                                   
2747          final FolderInfo info = folderIcon.getFolderInfo();                                                       
2748          Folder openFolder = mWorkspace.getFolderForTag(info);                                                     
2749                                                                                                                    
2750          // If the folder info reports that the associated folder is open, then verify that                        
2751          // it is actually opened. There have been a few instances where this gets out of sync.                    
2752          if (info.opened && openFolder == null) {                                                                  
2753              Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "                  
2754                      + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");                               
2755              info.opened = false;                                                                                  
2756          }                                                                                                         
2757                                                                                                                    
2758          if (!info.opened && !folderIcon.getFolder().isDestroyed()) {                                              
2759              // Close any open folder                                                                              
2760              closeFolder();                                                                                        
2761              // Open the requested folder                                                                          
2762              openFolder(folderIcon);                                                                               
2763          } else {                                                                                                  
2764              // Find the open folder...                                                                            
2765              int folderScreen;                                                                                     
2766              if (openFolder != null) {                                                                             
2767                  folderScreen = mWorkspace.getPageForView(openFolder);                                             
2768                  // .. and close it                                                                                
2769                  closeFolder(openFolder);                                                                          
2770                  if (folderScreen != mWorkspace.getCurrentPage()) {                                                
2771                      // Close any folder open on the current screen                                                
2772                      closeFolder();                                                                                
2773                      // Pull the folder onto this screen                                                           
2774                      openFolder(folderIcon);                                                                       
2775                  }                                                                                                 
2776              }                                                                                                     
2777          }                                                                                                         
2778                                                                                                                    
2779          if (mLauncherCallbacks != null) {                                                                         
2780              mLauncherCallbacks.onClickFolderIcon(v);                                                              
2781          }                                                                                                         
2782      }                                                                                                             
2783                                                                                                                    
2784      /**                                                                                                           
2785       * Event handler for the (Add) Widgets button that appears after a long press                                 
2786       * on the home screen.                                                                                        
2787       */                                                                                                           
2788      protected void onClickAddWidgetButton(View view) {                                                            
2789          if (LOGD) Log.d(TAG, "onClickAddWidgetButton");                                                           
2790          if (mIsSafeModeEnabled) {                                                                                 
2791              Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();                      
2792          } else {                                                                                                  
2793              showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);                                  

2794              if (mLauncherCallbacks != null) {                                                                     
2795                  mLauncherCallbacks.onClickAddWidgetButton(view);                                                  
2796              }                                                                                                     
2797          }                                                                                                         
2798      }                                                                                                             
2799                                                                                                                    
2800      /**                                                                                                           
2801       * Event handler for the wallpaper picker button that appears after a long press                              
2802       * on the home screen.                                                                                        
2803       */                                                                                                           
2804      protected void onClickWallpaperPicker(View v) {                                                               
2805          if (LOGD) Log.d(TAG, "onClickWallpaperPicker");                                                           
2806          final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);                                     
2807          pickWallpaper.setComponent(getWallpaperPickerComponent());                                                
2808          startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);                                            


2809                                                                                                                    
2810          if (mLauncherCallbacks != null) {                                                                         
2811              mLauncherCallbacks.onClickWallpaperPicker(v);                                                         
2812          }                                                                                                         
2813      }                                                                                                             
2814                                                                                                                    
2815      /**                                                                                                           
2816       * Event handler for a click on the settings button that appears after a long press                           
2817       * on the home screen.                                                                                        
2818       */                                                                                                           
2819      protected void onClickSettingsButton(View v) {                                                                
2820          if (LOGD) Log.d(TAG, "onClickSettingsButton");                                                            
2821          if (mLauncherCallbacks != null) {                                                                         
2822              mLauncherCallbacks.onClickSettingsButton(v);                                                          
2823          }                                                                                                         
2824      }                                                                                                             
2825                                                                                                                    
2826      public void onTouchDownAllAppsButton(View v) {                                                                
2827          // Provide the same haptic feedback that the system offers for virtual keys.                              
2828          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2829      }                                                                                                             
2830                                                                                                                    
2831      public void performHapticFeedbackOnTouchDown(View v) {                                                        
2832          // Provide the same haptic feedback that the system offers for virtual keys.                              
2833          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                                             
2834      }                                                                                                             
2835                                                                                                                    
2836      public View.OnTouchListener getHapticFeedbackTouchListener() {                                                
2837          if (mHapticFeedbackTouchListener == null) {                                                               
2838              mHapticFeedbackTouchListener = new View.OnTouchListener() {                                           
2839                  @Override                                                                                         
2840                  public boolean onTouch(View v, MotionEvent event) {                                               
2841                      if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {               
2842                          v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);                             
2843                      }                                                                                             
2844                      return false;                                                                                 
2845                  }                                                                                                 
2846              };                                                                                                    
2847          }                                                                                                         
2848          return mHapticFeedbackTouchListener;                                                                      
2849      }                                                                                                             
2850                                                                                                                    
2851      public void onDragStarted(View view) {                                                                        
2852          if (isOnCustomContent()) {                                                                                
2853              // Custom content screen doesn't participate in drag and drop. If on custom                           
2854              // content screen, move to default.                                                                   
2855              moveWorkspaceToDefaultScreen();                                                                       
2856          }                                                                                                         
2857                                                                                                                    
2858          if (mLauncherCallbacks != null) {                                                                         
2859              mLauncherCallbacks.onDragStarted(view);                                                               
2860          }                                                                                                         
2861      }                                                                                                             
2862                                                                                                                    
2863      /**                                                                                                           
2864       * Called when the user stops interacting with the launcher.                                                  
2865       * This implies that the user is now on the homescreen and is not doing housekeeping.                         
2866       */                                                                                                           
2867      protected void onInteractionEnd() {                                                                           
2868          if (mLauncherCallbacks != null) {                                                                         
2869              mLauncherCallbacks.onInteractionEnd();                                                                
2870          }                                                                                                         
2871      }                                                                                                             
2872                                                                                                                    
2873      /**                                                                                                           
2874       * Called when the user starts interacting with the launcher.                                                 
2875       * The possible interactions are:                                                                             
2876       *  - open all apps                                                                                           
2877       *  - reorder an app shortcut, or a widget                                                                    
2878       *  - open the overview mode.                                                                                 
2879       * This is a good time to stop doing things that only make sense                                              
2880       * when the user is on the homescreen and not doing housekeeping.                                             
2881       */                                                                                                           
2882      protected void onInteractionBegin() {                                                                         
2883          if (mLauncherCallbacks != null) {                                                                         
2884              mLauncherCallbacks.onInteractionBegin();                                                              
2885          }                                                                                                         
2886      }                                                                                                             
2887                                                                                                                    
2888      void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {                    
2889          try {                                                                                                     
2890              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2891              launcherApps.showAppDetailsForProfile(componentName, user);                                           
2892          } catch (SecurityException e) {                                                                           
2893              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2894              Log.e(TAG, "Launcher does not have permission to launch settings");                                   
2895          } catch (ActivityNotFoundException e) {                                                                   
2896              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2897              Log.e(TAG, "Unable to launch settings");                                                              
2898          }                                                                                                         
2899      }                                                                                                             
2900                                                                                                                    
2901      // returns true if the activity was started                                                                   
2902      boolean startApplicationUninstallActivity(ComponentName componentName, int flags,                             
2903              UserHandleCompat user) {                                                                              
2904          if ((flags & AppInfo.DOWNLOADED_FLAG) == 0) {                                                             
2905              // System applications cannot be installed. For now, show a toast explaining that.                    
2906              // We may give them the option of disabling apps this way.                                            
2907              int messageId = R.string.uninstall_system_app_text;                                                   
2908              Toast.makeText(this, messageId, Toast.LENGTH_SHORT).show();                                           
2909              return false;                                                                                         
2910          } else {                                                                                                  
2911              String packageName = componentName.getPackageName();                                                  
2912              String className = componentName.getClassName();                                                      
2913              Intent intent = new Intent(                                                                           
2914                      Intent.ACTION_DELETE, Uri.fromParts("package", packageName, className));                      
2915              intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |                                                       
2916                      Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);                                                   
2917              if (user != null) {                                                                                   
2918                  user.addToIntent(intent, Intent.EXTRA_USER);                                                      
2919              }                                                                                                     
2920              startActivity(intent);                                                                                
2921              return true;                                                                                          
2922          }                                                                                                         
2923      }                                                                                                             
2924                                                                                                                    
2925      boolean startActivity(View v, Intent intent, Object tag) {                                                    
2926          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                           
2927          try {                                                                                                     
2928              // Only launch using the new animation if the shortcut has not opted out (this is a                   
2929              // private contract between launcher and may be ignored in the future).                               
2930              boolean useLaunchAnimation = (v != null) &&                                                           
2931                      !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);                                       
2932              LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                               
2933              UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                  
2934                                                                                                                    
2935              UserHandleCompat user = null;                                                                         
2936              if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) {                                                         
2937                  long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1);                               
2938                  user = userManager.getUserForSerialNumber(serialNumber);                                          
2939              }                                                                                                     
2940                                                                                                                    
2941              Bundle optsBundle = null;                                                                             
2942 -            if (useLaunchAnimation) {                                                                             
2943 -                ActivityOptions opts = Utilities.isLmpOrAbove() ?                                                 
2944 -                        ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim) :       
2945 +            if (useLaunchAnimation && !Utilities.isLmpOrAbove()) {                                                
2946 +                // On pre-L devices, we use the scale up transition.                                              
2947 +                // Otherwise we use system default.                                                               
2948 +                ActivityOptions opts =                                                                            
2949                          ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight())🔵
2950                  optsBundle = opts.toBundle();                                                                     
































2951              }                                                                                                     
2952                                                                                                                    
2953              if (user == null || user.equals(UserHandleCompat.myUserHandle())) {                                   
2954                  // Could be launching some bookkeeping activity                                                   
2955                  startActivity(intent, optsBundle);                                                                
2956              } else {                                                                                              
2957                  // TODO Component can be null when shortcuts are supported for secondary user                     
2958                  launcherApps.startActivityForProfile(intent.getComponent(), user,                                 
2959                          intent.getSourceBounds(), optsBundle);                                                    
2960              }                                                                                                     
2961              return true;                                                                                          
2962          } catch (SecurityException e) {                                                                           
2963              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2964              Log.e(TAG, "Launcher does not have the permission to launch " + intent +                              
2965                      ". Make sure to create a MAIN intent-filter for the corresponding activity " +                
2966                      "or use the exported attribute for this activity. "                                           
2967                      + "tag="+ tag + " intent=" + intent, e);                                                      
2968          }                                                                                                         
2969          return false;                                                                                             
2970      }                                                                                                             
2971                                                                                                                    
2972      boolean startActivitySafely(View v, Intent intent, Object tag) {                                              
2973          boolean success = false;                                                                                  
2974          if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {                                         
2975              Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();                    
2976              return false;                                                                                         
2977          }                                                                                                         
2978          try {                                                                                                     
2979              success = startActivity(v, intent, tag);                                                              
2980          } catch (ActivityNotFoundException e) {                                                                   
2981              Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();                         
2982              Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);                                  
2983          }                                                                                                         
2984          return success;                                                                                           
2985      }                                                                                                             
2986                                                                                                                    
2987      /**                                                                                                           
2988       * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView                
2989       * in the DragLayer in the exact absolute location of the original FolderIcon.                                
2990       */                                                                                                           
2991      private void copyFolderIconToImage(FolderIcon fi) {                                                           
2992          final int width = fi.getMeasuredWidth();                                                                  
2993          final int height = fi.getMeasuredHeight();                                                                
2994                                                                                                                    
2995          // Lazy load ImageView, Bitmap and Canvas                                                                 
2996          if (mFolderIconImageView == null) {                                                                       
2997              mFolderIconImageView = new ImageView(this);                                                           
2998          }                                                                                                         
2999          if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||                                 
3000                  mFolderIconBitmap.getHeight() != height) {                                                        
3001              mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);                      
3002              mFolderIconCanvas = new Canvas(mFolderIconBitmap);                                                    
3003          }                                                                                                         
3004                                                                                                                    
3005          DragLayer.LayoutParams lp;                                                                                
3006          if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {                           
3007              lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();                                 
3008          } else {                                                                                                  
3009              lp = new DragLayer.LayoutParams(width, height);                                                       
3010          }                                                                                                         
3011                                                                                                                    
3012          // The layout from which the folder is being opened may be scaled, adjust the starting                    
3013          // view size by this scale factor.                                                                        
3014          float scale = mDragLayer.getDescendantRectRelativeToSelf(fi, mRectForFolderAnimation);                    
3015          lp.customPosition = true;                                                                                 
3016          lp.x = mRectForFolderAnimation.left;                                                                      
3017          lp.y = mRectForFolderAnimation.top;                                                                       
3018          lp.width = (int) (scale * width);                                                                         
3019          lp.height = (int) (scale * height);                                                                       
3020                                                                                                                    
3021          mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);                                                    
3022          fi.draw(mFolderIconCanvas);                                                                               
3023          mFolderIconImageView.setImageBitmap(mFolderIconBitmap);                                                   
3024          if (fi.getFolder() != null) {                                                                             
3025              mFolderIconImageView.setPivotX(fi.getFolder().getPivotXForIconAnimation());                           
3026              mFolderIconImageView.setPivotY(fi.getFolder().getPivotYForIconAnimation());                           
3027          }                                                                                                         
3028          // Just in case this image view is still in the drag layer from a previous animation,                     
3029          // we remove it and re-add it.                                                                            
3030          if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {                                                
3031              mDragLayer.removeView(mFolderIconImageView);                                                          
3032          }                                                                                                         
3033          mDragLayer.addView(mFolderIconImageView, lp);                                                             
3034          if (fi.getFolder() != null) {                                                                             
3035              fi.getFolder().bringToFront();                                                                        
3036          }                                                                                                         
3037      }                                                                                                             
3038                                                                                                                    
3039      private void growAndFadeOutFolderIcon(FolderIcon fi) {                                                        
3040          if (fi == null) return;                                                                                   
3041          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);                                    
3042          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);                               
3043          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);                               
3044                                                                                                                    
3045          FolderInfo info = (FolderInfo) fi.getTag();                                                               
3046          if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                     
3047              CellLayout cl = (CellLayout) fi.getParent().getParent();                                              
3048              CellLayout.LayoutParams lp = (CellLayout.LayoutParams) fi.getLayoutParams();                          
3049              cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);                                                      
3050          }                                                                                                         
3051                                                                                                                    
3052          // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original                      
3053          copyFolderIconToImage(fi);                                                                                
3054          fi.setVisibility(View.INVISIBLE);                                                                         
3055                                                                                                                    
3056          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3057                  scaleX, scaleY);                                                                                  
3058          if (Utilities.isLmpOrAbove()) {                                                                           
3059              oa.setInterpolator(new LogDecelerateInterpolator(100, 0));                                            
3060          }                                                                                                         
3061          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3062          oa.start();                                                                                               
3063      }                                                                                                             
3064                                                                                                                    
3065      private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {                                                 
3066          if (fi == null) return;                                                                                   
3067          PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);                                 
3068          PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);                               
3069          PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);                               
3070                                                                                                                    
3071          final CellLayout cl = (CellLayout) fi.getParent().getParent();                                            
3072                                                                                                                    
3073          // We remove and re-draw the FolderIcon in-case it has changed                                            
3074          mDragLayer.removeView(mFolderIconImageView);                                                              
3075          copyFolderIconToImage(fi);                                                                                
3076          ObjectAnimator oa = LauncherAnimUtils.ofPropertyValuesHolder(mFolderIconImageView, alpha,                 
3077                  scaleX, scaleY);                                                                                  
3078          oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));                         
3079          oa.addListener(new AnimatorListenerAdapter() {                                                            
3080              @Override                                                                                             
3081              public void onAnimationEnd(Animator animation) {                                                      
3082                  if (cl != null) {                                                                                 
3083                      cl.clearFolderLeaveBehind();                                                                  
3084                      // Remove the ImageView copy of the FolderIcon and make the original visible.                 
3085                      mDragLayer.removeView(mFolderIconImageView);                                                  
3086                      fi.setVisibility(View.VISIBLE);                                                               
3087                  }                                                                                                 
3088              }                                                                                                     
3089          });                                                                                                       
3090          oa.start();                                                                                               
3091      }                                                                                                             
3092                                                                                                                    
3093      /**                                                                                                           
3094       * Opens the user folder described by the specified tag. The opening of the folder                            
3095       * is animated relative to the specified View. If the View is null, no animation                              
3096       * is played.                                                                                                 
3097       *                                                                                                            
3098       * @param folderInfo The FolderInfo describing the folder to open.                                            
3099       */                                                                                                           
3100      public void openFolder(FolderIcon folderIcon) {                                                               
3101          Folder folder = folderIcon.getFolder();                                                                   






3102          FolderInfo info = folder.mInfo;                                                                           
3103                                                                                                                    
3104          info.opened = true;                                                                                       



3105                                                                                                                    
3106          // Just verify that the folder hasn't already been added to the DragLayer.                                
3107          // There was a one-off crash where the folder had a parent already.                                       
3108          if (folder.getParent() == null) {                                                                         
3109              mDragLayer.addView(folder);                                                                           
3110              mDragController.addDropTarget((DropTarget) folder);                                                   
3111          } else {                                                                                                  
3112              Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +                           
3113                      folder.getParent() + ").");                                                                   
3114          }                                                                                                         
3115          folder.animateOpen();                                                                                     
3116          growAndFadeOutFolderIcon(folderIcon);                                                                     
3117                                                                                                                    
3118          // Notify the accessibility manager that this folder "window" has appeared and occluded                   
3119          // the workspace items                                                                                    
3120          folder.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                              
3121          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);                    
3122      }                                                                                                             
3123                                                                                                                    
3124      public void closeFolder() {                                                                                   
3125          Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;                                   
3126          if (folder != null) {                                                                                     
3127              if (folder.isEditingName()) {                                                                         
3128                  folder.dismissEditingName();                                                                      
3129              }                                                                                                     
3130              closeFolder(folder);                                                                                  
3131          }                                                                                                         
3132      }                                                                                                             
3133                                                                                                                    
3134      void closeFolder(Folder folder) {                                                                             
3135          folder.getInfo().opened = false;                                                                          
3136                                                                                                                    
3137          ViewGroup parent = (ViewGroup) folder.getParent().getParent();                                            
3138          if (parent != null) {                                                                                     
3139              FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);                                  
3140              shrinkAndFadeInFolderIcon(fi);                                                                        



3141          }                                                                                                         
3142          folder.animateClosed();                                                                                   
3143                                                                                                                    
3144          // Notify the accessibility manager that this folder "window" has disappeard and no                       
3145          // longer occludeds the workspace items                                                                   
3146          getDragLayer().sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                      
3147      }                                                                                                             
3148                                                                                                                    
3149      public boolean onLongClick(View v) {                                                                          
3150          if (!isDraggingEnabled()) return false;                                                                   
3151          if (isWorkspaceLocked()) return false;                                                                    
3152          if (mState != State.WORKSPACE) return false;                                                              
3153                                                                                                                    
3154          if (v instanceof Workspace) {                                                                             
3155              if (!mWorkspace.isInOverviewMode()) {                                                                 
3156                  if (mWorkspace.enterOverviewMode()) {                                                             
3157                      mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                          
3158                              HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                    
3159                      return true;                                                                                  
3160                  } else {                                                                                          
3161                      return false;                                                                                 
3162                  }                                                                                                 
3163              } else {                                                                                              
3164                  return false;                                                                                     
3165              }                                                                                                     
3166          }                                                                                                         
3167                                                                                                                    
3168          CellLayout.CellInfo longClickCellInfo = null;                                                             
3169          View itemUnderLongClick = null;                                                                           
3170          if (v.getTag() instanceof ItemInfo) {                                                                     
3171              ItemInfo info = (ItemInfo) v.getTag();                                                                
3172              longClickCellInfo = new CellLayout.CellInfo(v, info);;                                                

3173              itemUnderLongClick = longClickCellInfo.cell;                                                          
3174              resetAddInfo();                                                                                       
3175          }                                                                                                         
3176                                                                                                                    
3177          // The hotseat touch handling does not go through Workspace, and we always allow long press               
3178          // on hotseat items.                                                                                      
3179          final boolean inHotseat = isHotseatLayout(v);                                                             
3180          boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();                                        
3181          if (allowLongPress && !mDragController.isDragging()) {                                                    
3182              if (itemUnderLongClick == null) {                                                                     
3183                  // User long pressed on empty space                                                               
3184                  mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,                              
3185                          HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);                                        
3186                  if (mWorkspace.isInOverviewMode()) {                                                              
3187                      mWorkspace.startReordering(v);                                                                
3188                  } else {                                                                                          
3189                      mWorkspace.enterOverviewMode();                                                               
3190                  }                                                                                                 
3191              } else {                                                                                              
3192                  final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(                                 
3193                          mHotseat.getOrderInHotseat(                                                               
3194                                  longClickCellInfo.cellX,                                                          
3195                                  longClickCellInfo.cellY));                                                        
3196                  if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {                                 
3197                      // User long pressed on an item                                                               
3198                      mWorkspace.startDrag(longClickCellInfo);                                                      
3199                  }                                                                                                 
3200              }                                                                                                     
3201          }                                                                                                         
3202          return true;                                                                                              
3203      }                                                                                                             
3204                                                                                                                    
3205      boolean isHotseatLayout(View layout) {                                                                        
3206          return mHotseat != null && layout != null &&                                                              
3207                  (layout instanceof CellLayout) && (layout == mHotseat.getLayout());                               
3208      }                                                                                                             
3209                                                                                                                    
3210      /**                                                                                                           
3211       * Returns the CellLayout of the specified container at the specified screen.                                 
3212       */                                                                                                           
3213      CellLayout getCellLayout(long container, long screenId) {                                                     

3214          if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {                                          
3215              if (mHotseat != null) {                                                                               
3216                  return mHotseat.getLayout();                                                                      
3217              } else {                                                                                              
3218                  return null;                                                                                      
3219              }                                                                                                     
3220          } else {                                                                                                  
3221              return (CellLayout) mWorkspace.getScreenWithId(screenId);                                             
3222          }                                                                                                         
3223      }                                                                                                             
3224                                                                                                                    







3225      public boolean isAllAppsVisible() {                                                                           
3226          return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);                      









3227      }                                                                                                             
3228                                                                                                                    
3229      private void setWorkspaceBackground(boolean workspace) {                                                      
3230          mLauncherView.setBackground(workspace ?                                                                   
3231                  mWorkspaceBackgroundDrawable : null);                                                             
3232      }                                                                                                             
3233                                                                                                                    
3234      protected void changeWallpaperVisiblity(boolean visible) {                                                    
3235          int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;                               
3236          int curflags = getWindow().getAttributes().flags                                                          
3237                  & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;                                                 
3238          if (wpflags != curflags) {                                                                                
3239              getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);                        
3240          }                                                                                                         
3241          setWorkspaceBackground(visible);                                                                          
3242      }                                                                                                             
3243                                                                                                                    
3244      private void dispatchOnLauncherTransitionPrepare(View v, boolean animated, boolean toWorkspace) {             
3245          if (v instanceof LauncherTransitionable) {                                                                
3246              ((LauncherTransitionable) v).onLauncherTransitionPrepare(this, animated, toWorkspace);                
3247          }                                                                                                         
3248      }                                                                                                             
3249                                                                                                                    
3250      private void dispatchOnLauncherTransitionStart(View v, boolean animated, boolean toWorkspace) {               
3251          if (v instanceof LauncherTransitionable) {                                                                
3252              ((LauncherTransitionable) v).onLauncherTransitionStart(this, animated, toWorkspace);                  
3253          }                                                                                                         
3254                                                                                                                    
3255          // Update the workspace transition step as well                                                           
3256          dispatchOnLauncherTransitionStep(v, 0f);                                                                  
3257      }                                                                                                             
3258                                                                                                                    
3259      private void dispatchOnLauncherTransitionStep(View v, float t) {                                              
3260          if (v instanceof LauncherTransitionable) {                                                                
3261              ((LauncherTransitionable) v).onLauncherTransitionStep(this, t);                                       
3262          }                                                                                                         
3263      }                                                                                                             
3264                                                                                                                    
3265      private void dispatchOnLauncherTransitionEnd(View v, boolean animated, boolean toWorkspace) {                 
3266          if (v instanceof LauncherTransitionable) {                                                                
3267              ((LauncherTransitionable) v).onLauncherTransitionEnd(this, animated, toWorkspace);                    
3268          }                                                                                                         
3269                                                                                                                    
3270          // Update the workspace transition step as well                                                           
3271          dispatchOnLauncherTransitionStep(v, 1f);                                                                  
3272      }                                                                                                             
3273                                                                                                                    
3274      /**                                                                                                           
3275       * Things to test when changing the following seven functions.                                                
3276       *   - Home from workspace                                                                                    
3277       *          - from center screen                                                                              
3278       *          - from other screens                                                                              
3279       *   - Home from all apps                                                                                     
3280       *          - from center screen                                                                              
3281       *          - from other screens                                                                              
3282       *   - Back from all apps                                                                                     
3283       *          - from center screen                                                                              
3284       *          - from other screens                                                                              
3285       *   - Launch app from workspace and quit                                                                     
3286       *          - with back                                                                                       
3287       *          - with home                                                                                       
3288       *   - Launch app from all apps and quit                                                                      
3289       *          - with back                                                                                       
3290       *          - with home                                                                                       
3291       *   - Go to a screen that's not the default, then all                                                        
3292       *     apps, and launch and app, and go back                                                                  
3293       *          - with back                                                                                       
3294       *          -with home                                                                                        
3295       *   - On workspace, long press power and go back                                                             
3296       *          - with back                                                                                       
3297       *          - with home                                                                                       
3298       *   - On all apps, long press power and go back                                                              
3299       *          - with back                                                                                       
3300       *          - with home                                                                                       
3301       *   - On workspace, power off                                                                                
3302       *   - On all apps, power off                                                                                 
3303       *   - Launch an app and turn off the screen while in that app                                                
3304       *          - Go back with home key                                                                           
3305       *          - Go back with back key  TODO: make this not go to workspace                                      
3306       *          - From all apps                                                                                   
3307       *          - From workspace                                                                                  
3308       *   - Enter and exit car mode (becuase it causes an extra configuration changed)                             
3309       *          - From all apps                                                                                   
3310       *          - From the center workspace                                                                       
3311       *          - From another workspace                                                                          
3312       */                                                                                                           
3313                                                                                                                    
3314      /**                                                                                                           
3315       * Zoom the camera out from the workspace to reveal 'toView'.                                                 
3316       * Assumes that the view to show is anchored at either the very top or very bottom                            
3317       * of the screen.                                                                                             
3318       */                                                                                                           
3319      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {                    
3320          AppsCustomizePagedView.ContentType contentType = mAppsCustomizeContent.getContentType();                  
3321          showAppsCustomizeHelper(animated, springLoaded, contentType);                                             
3322      }                                                                                                             
3323                                                                                                                    
3324      @TargetApi(Build.VERSION_CODES.LOLLIPOP)                                                                      
3325      private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded,                      
3326                                           final AppsCustomizePagedView.ContentType contentType) {                  
3327          if (mStateAnimation != null) {                                                                            
3328              mStateAnimation.setDuration(0);                                                                       
3329              mStateAnimation.cancel();                                                                             
3330              mStateAnimation = null;                                                                               
3331          }                                                                                                         
3332                                                                                                                    
3333          boolean material = Utilities.isLmpOrAbove();                                                              
3334                                                                                                                    
3335          final Resources res = getResources();                                                                     
3336                                                                                                                    
3337          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeRevealTime);                      
3338          final int itemsAlphaStagger =                                                                             
3339                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3340                                                                                                                    
3341          final View fromView = mWorkspace;                                                                         
3342          final AppsCustomizeTabHost toView = mAppsCustomizeTabHost;                                                
3343                                                                                                                    
3344          final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3345                                                                                                                    
3346          Workspace.State workspaceState = contentType == AppsCustomizePagedView.ContentType.Widgets ?              
3347                  Workspace.State.OVERVIEW_HIDDEN : Workspace.State.NORMAL_HIDDEN;                                  
3348          Animator workspaceAnim =                                                                                  
3349                  mWorkspace.getChangeStateAnimation(workspaceState, animated, layerViews);                         
3350          if (!LauncherAppState.isDisableAllApps()                                                                  
3351                  || contentType == AppsCustomizePagedView.ContentType.Widgets) {                                   
3352              // Set the content type for the all apps/widgets space                                                
3353              mAppsCustomizeTabHost.setContentTypeImmediate(contentType);                                           
3354          }                                                                                                         
3355                                                                                                                    
3356          // If for some reason our views aren't initialized, don't animate                                         
3357          boolean initialized = getAllAppsButton() != null;                                                         
3358                                                                                                                    
3359          if (animated && initialized) {                                                                            
3360              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3361              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3362                      toView.findViewById(R.id.apps_customize_pane_content);                                        
3363                                                                                                                    
3364              final View page = content.getPageAt(content.getCurrentPage());                                        
3365              final View revealView = toView.findViewById(R.id.fake_page);                                          
3366                                                                                                                    
3367              final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;               
3368              if (isWidgetTray) {                                                                                   
3369                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                         
3370              } else {                                                                                              
3371                  revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                              
3372              }                                                                                                     
3373                                                                                                                    
3374              // Hide the real page background, and swap in the fake one                                            
3375              content.setPageBackgroundsVisible(false);                                                             
3376              revealView.setVisibility(View.VISIBLE);                                                               
3377              // We need to hide this view as the animation start will be posted.                                   
3378              revealView.setAlpha(0);                                                                               
3379                                                                                                                    
3380              int width = revealView.getMeasuredWidth();                                                            
3381              int height = revealView.getMeasuredHeight();                                                          
3382              float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);                  
3383                                                                                                                    
3384              revealView.setTranslationY(0);                                                                        
3385              revealView.setTranslationX(0);                                                                        
3386                                                                                                                    
3387              // Get the y delta between the center of the page and the center of the all apps button               
3388              int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                         
3389                      getAllAppsButton(), null);                                                                    
3390                                                                                                                    
3391              float alpha = 0;                                                                                      
3392              float xDrift = 0;                                                                                     
3393              float yDrift = 0;                                                                                     
3394              if (material) {                                                                                       
3395                  alpha = isWidgetTray ? 0.3f : 1f;                                                                 
3396                  yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                      
3397                  xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                               
3398              } else {                                                                                              
3399                  yDrift = 2 * height / 3;                                                                          
3400                  xDrift = 0;                                                                                       
3401              }                                                                                                     
3402              final float initAlpha = alpha;                                                                        
3403                                                                                                                    
3404              layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                      
3405              PropertyValuesHolder panelAlpha = PropertyValuesHolder.ofFloat("alpha", initAlpha, 1f);               
3406              PropertyValuesHolder panelDriftY =                                                                    
3407                      PropertyValuesHolder.ofFloat("translationY", yDrift, 0);                                      
3408              PropertyValuesHolder panelDriftX =                                                                    
3409                      PropertyValuesHolder.ofFloat("translationX", xDrift, 0);                                      
3410                                                                                                                    
3411              ObjectAnimator panelAlphaAndDrift = ObjectAnimator.ofPropertyValuesHolder(revealView,                 
3412                      panelAlpha, panelDriftY, panelDriftX);                                                        
3413                                                                                                                    
3414              panelAlphaAndDrift.setDuration(revealDuration);                                                       
3415              panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                            
3416                                                                                                                    
3417              mStateAnimation.play(panelAlphaAndDrift);                                                             
3418                                                                                                                    
3419              if (page != null) {                                                                                   
3420                  page.setVisibility(View.VISIBLE);                                                                 
3421                  layerViews.put(page, BUILD_AND_SET_LAYER);                                                        
3422                                                                                                                    
3423                  ObjectAnimator pageDrift = ObjectAnimator.ofFloat(page, "translationY", yDrift, 0);               
3424                  page.setTranslationY(yDrift);                                                                     
3425                  pageDrift.setDuration(revealDuration);                                                            
3426                  pageDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));                                 
3427                  pageDrift.setStartDelay(itemsAlphaStagger);                                                       
3428                  mStateAnimation.play(pageDrift);                                                                  
3429                                                                                                                    
3430                  page.setAlpha(0f);                                                                                
3431                  ObjectAnimator itemsAlpha = ObjectAnimator.ofFloat(page, "alpha", 0f, 1f);                        
3432                  itemsAlpha.setDuration(revealDuration);                                                           
3433                  itemsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));                                     
3434                  itemsAlpha.setStartDelay(itemsAlphaStagger);                                                      
3435                  mStateAnimation.play(itemsAlpha);                                                                 
3436              }                                                                                                     
3437                                                                                                                    
3438              View pageIndicators = toView.findViewById(R.id.apps_customize_page_indicator);                        
3439              pageIndicators.setAlpha(0.01f);                                                                       
3440              ObjectAnimator indicatorsAlpha =                                                                      
3441                      ObjectAnimator.ofFloat(pageIndicators, "alpha", 1f);                                          
3442              indicatorsAlpha.setDuration(revealDuration);                                                          
3443              mStateAnimation.play(indicatorsAlpha);                                                                
3444                                                                                                                    
3445              if (material) {                                                                                       
3446                  final View allApps = getAllAppsButton();                                                          
3447                  int allAppsButtonSize = LauncherAppState.getInstance().                                           
3448                          getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                              
3449                  float startRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                     
3450                  Animator reveal = ViewAnimationUtils.createCircularReveal(revealView, width / 2,                  
3451                                  height / 2, startRadius, revealRadius);                                           
3452                  reveal.setDuration(revealDuration);                                                               
3453                  reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                    
3454                                                                                                                    
3455                  reveal.addListener(new AnimatorListenerAdapter() {                                                
3456                      public void onAnimationStart(Animator animation) {                                            
3457                          if (!isWidgetTray) {                                                                      
3458                              allApps.setVisibility(View.INVISIBLE);                                                
3459                          }                                                                                         
3460                      }                                                                                             
3461                      public void onAnimationEnd(Animator animation) {                                              
3462                          if (!isWidgetTray) {                                                                      
3463                              allApps.setVisibility(View.VISIBLE);                                                  
3464                          }                                                                                         
3465                      }                                                                                             
3466                  });                                                                                               
3467                  mStateAnimation.play(reveal);                                                                     
3468              }                                                                                                     
3469                                                                                                                    
3470              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3471                  @Override                                                                                         
3472                  public void onAnimationEnd(Animator animation) {                                                  
3473                      dispatchOnLauncherTransitionEnd(fromView, animated, false);                                   
3474                      dispatchOnLauncherTransitionEnd(toView, animated, false);                                     
3475                                                                                                                    
3476                      revealView.setVisibility(View.INVISIBLE);                                                     
3477                                                                                                                    
3478                      for (View v : layerViews.keySet()) {                                                          
3479                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3480                              v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3481                          }                                                                                         
3482                      }                                                                                             
3483                      content.setPageBackgroundsVisible(true);                                                      
3484                                                                                                                    
3485                      // Hide the search bar                                                                        
3486                      if (mSearchDropTargetBar != null) {                                                           
3487                          mSearchDropTargetBar.hideSearchBar(false);                                                
3488                      }                                                                                             
3489                                                                                                                    
3490                      // This can hold unnecessary references to views.                                             
3491                      mStateAnimation = null;                                                                       
3492                  }                                                                                                 
3493                                                                                                                    
3494              });                                                                                                   
3495                                                                                                                    
3496              if (workspaceAnim != null) {                                                                          
3497                  mStateAnimation.play(workspaceAnim);                                                              
3498              }                                                                                                     
3499                                                                                                                    
3500              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3501              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3502              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3503              final Runnable startAnimRunnable = new Runnable() {                                                   
3504                  public void run() {                                                                               
3505                      // Check that mStateAnimation hasn't changed while                                            
3506                      // we waited for a layout/draw pass                                                           
3507                      if (mStateAnimation != stateAnimation)                                                        
3508                          return;                                                                                   
3509                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3510                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3511                                                                                                                    
3512                      revealView.setAlpha(initAlpha);                                                               
3513                                                                                                                    
3514                      for (View v : layerViews.keySet()) {                                                          
3515                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3516                              v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3517                          }                                                                                         
3518                      }                                                                                             
3519                                                                                                                    
3520                      if (Utilities.isLmpOrAbove()) {                                                               
3521                          for (View v : layerViews.keySet()) {                                                      
3522                              if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3523                          }                                                                                         
3524                      }                                                                                             
3525                      mStateAnimation.start();                                                                      
3526                  }                                                                                                 
3527              };                                                                                                    
3528              toView.bringToFront();                                                                                
3529              toView.setVisibility(View.VISIBLE);                                                                   
3530              toView.post(startAnimRunnable);                                                                       
3531          } else {                                                                                                  
3532              toView.setTranslationX(0.0f);                                                                         
3533              toView.setTranslationY(0.0f);                                                                         
3534              toView.setScaleX(1.0f);                                                                               
3535              toView.setScaleY(1.0f);                                                                               
3536              toView.setVisibility(View.VISIBLE);                                                                   
3537              toView.bringToFront();                                                                                
3538                                                                                                                    
3539              if (!springLoaded && !LauncherAppState.getInstance().isScreenLarge()) {                               
3540                  // Hide the search bar                                                                            
3541                  if (mSearchDropTargetBar != null) {                                                               
3542                      mSearchDropTargetBar.hideSearchBar(false);                                                    
3543                  }                                                                                                 
3544              }                                                                                                     
3545              dispatchOnLauncherTransitionPrepare(fromView, animated, false);                                       
3546              dispatchOnLauncherTransitionStart(fromView, animated, false);                                         
3547              dispatchOnLauncherTransitionEnd(fromView, animated, false);                                           
3548              dispatchOnLauncherTransitionPrepare(toView, animated, false);                                         
3549              dispatchOnLauncherTransitionStart(toView, animated, false);                                           
3550              dispatchOnLauncherTransitionEnd(toView, animated, false);                                             
3551          }                                                                                                         
3552      }                                                                                                             
3553                                                                                                                    
3554      /**                                                                                                           
3555       * Zoom the camera back into the workspace, hiding 'fromView'.                                                
3556       * This is the opposite of showAppsCustomizeHelper.                                                           
3557       * @param animated If true, the transition will be animated.                                                  
3558       */                                                                                                           
3559      private void hideAppsCustomizeHelper(Workspace.State toState, final boolean animated,                         
3560              final boolean springLoaded, final Runnable onCompleteRunnable) {                                      
3561                                                                                                                    
3562          if (mStateAnimation != null) {                                                                            
3563              mStateAnimation.setDuration(0);                                                                       
3564              mStateAnimation.cancel();                                                                             
3565              mStateAnimation = null;                                                                               
3566          }                                                                                                         
3567                                                                                                                    
3568          boolean material = Utilities.isLmpOrAbove();                                                              
3569          Resources res = getResources();                                                                           
3570                                                                                                                    
3571          final int revealDuration = res.getInteger(R.integer.config_appsCustomizeConcealTime);                     
3572          final int itemsAlphaStagger =                                                                             
3573                  res.getInteger(R.integer.config_appsCustomizeItemsAlphaStagger);                                  
3574                                                                                                                    
3575          final View fromView = mAppsCustomizeTabHost;                                                              
3576          final View toView = mWorkspace;                                                                           
3577          Animator workspaceAnim = null;                                                                            
3578          final HashMap<View, Integer> layerViews = new HashMap<View, Integer>();                                   
3579                                                                                                                    
3580          if (toState == Workspace.State.NORMAL) {                                                                  
3581              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3582                      toState, animated, layerViews);                                                               
3583          } else if (toState == Workspace.State.SPRING_LOADED ||                                                    
3584                  toState == Workspace.State.OVERVIEW) {                                                            
3585              workspaceAnim = mWorkspace.getChangeStateAnimation(                                                   
3586                      toState, animated, layerViews);                                                               
3587          }                                                                                                         
3588                                                                                                                    
3589          // If for some reason our views aren't initialized, don't animate                                         
3590          boolean initialized = getAllAppsButton() != null;                                                         
3591                                                                                                                    
3592          if (animated && initialized) {                                                                            
3593              mStateAnimation = LauncherAnimUtils.createAnimatorSet();                                              
3594              if (workspaceAnim != null) {                                                                          
3595                  mStateAnimation.play(workspaceAnim);                                                              
3596              }                                                                                                     
3597                                                                                                                    
3598              final AppsCustomizePagedView content = (AppsCustomizePagedView)                                       
3599                      fromView.findViewById(R.id.apps_customize_pane_content);                                      
3600                                                                                                                    
3601              final View page = content.getPageAt(content.getNextPage());                                           
3602                                                                                                                    
3603              // We need to hide side pages of the Apps / Widget tray to avoid some ugly edge cases                 
3604              int count = content.getChildCount();                                                                  
3605              for (int i = 0; i < count; i++) {                                                                     
3606                  View child = content.getChildAt(i);                                                               
3607                  if (child != page) {                                                                              
3608                      child.setVisibility(View.INVISIBLE);                                                          
3609                  }                                                                                                 
3610              }                                                                                                     
3611              final View revealView = fromView.findViewById(R.id.fake_page);                                        
3612                                                                                                                    
3613              // hideAppsCustomizeHelper is called in some cases when it is already hidden                          
3614              // don't perform all these no-op animations. In particularly, this was causing                        
3615              // the all-apps button to pop in and out.                                                             
3616              if (fromView.getVisibility() == View.VISIBLE) {                                                       
3617                  AppsCustomizePagedView.ContentType contentType = content.getContentType();                        
3618                  final boolean isWidgetTray =                                                                      
3619                          contentType == AppsCustomizePagedView.ContentType.Widgets;                                
3620                                                                                                                    
3621                  if (isWidgetTray) {                                                                               
3622                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));                     
3623                  } else {                                                                                          
3624                      revealView.setBackground(res.getDrawable(R.drawable.quantum_panel));                          
3625                  }                                                                                                 
3626                                                                                                                    
3627                  int width = revealView.getMeasuredWidth();                                                        
3628                  int height = revealView.getMeasuredHeight();                                                      
3629                  float revealRadius = (float) Math.sqrt((width * width) / 4 + (height * height) / 4);              
3630                                                                                                                    
3631                  // Hide the real page background, and swap in the fake one                                        
3632                  revealView.setVisibility(View.VISIBLE);                                                           
3633                  content.setPageBackgroundsVisible(false);                                                         
3634                                                                                                                    
3635                  final View allAppsButton = getAllAppsButton();                                                    
3636                  revealView.setTranslationY(0);                                                                    
3637                  int[] allAppsToPanelDelta = Utilities.getCenterDeltaInScreenSpace(revealView,                     
3638                          allAppsButton, null);                                                                     
3639                                                                                                                    
3640                  float xDrift = 0;                                                                                 
3641                  float yDrift = 0;                                                                                 
3642                  if (material) {                                                                                   
3643                      yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];                                  
3644                      xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];                                           
3645                  } else {                                                                                          
3646                      yDrift = 2 * height / 3;                                                                      
3647                      xDrift = 0;                                                                                   
3648                  }                                                                                                 
3649                                                                                                                    
3650                  layerViews.put(revealView, BUILD_AND_SET_LAYER);                                                  
3651                  TimeInterpolator decelerateInterpolator = material ?                                              
3652                          new LogDecelerateInterpolator(100, 0) :                                                   
3653                          new DecelerateInterpolator(1f);                                                           
3654                                                                                                                    
3655                  // The vertical motion of the apps panel should be delayed by one frame                           
3656                  // from the conceal animation in order to give the right feel. We correpsondingly                 
3657                  // shorten the duration so that the slide and conceal end at the same time.                       
3658                  ObjectAnimator panelDriftY = LauncherAnimUtils.ofFloat(revealView, "translationY",                
3659                          0, yDrift);                                                                               
3660                  panelDriftY.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3661                  panelDriftY.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3662                  panelDriftY.setInterpolator(decelerateInterpolator);                                              
3663                  mStateAnimation.play(panelDriftY);                                                                
3664                                                                                                                    
3665                  ObjectAnimator panelDriftX = LauncherAnimUtils.ofFloat(revealView, "translationX",                
3666                          0, xDrift);                                                                               
3667                  panelDriftX.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                     
3668                  panelDriftX.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                                
3669                  panelDriftX.setInterpolator(decelerateInterpolator);                                              
3670                  mStateAnimation.play(panelDriftX);                                                                
3671                                                                                                                    
3672                  if (isWidgetTray || !material) {                                                                  
3673                      float finalAlpha = material ? 0.4f : 0f;                                                      
3674                      revealView.setAlpha(1f);                                                                      
3675                      ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",                    
3676                              1f, finalAlpha);                                                                      
3677                      panelAlpha.setDuration(material ? revealDuration : 150);                                      
3678                      panelAlpha.setInterpolator(decelerateInterpolator);                                           
3679                      panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);              
3680                      mStateAnimation.play(panelAlpha);                                                             
3681                  }                                                                                                 
3682                                                                                                                    
3683                  if (page != null) {                                                                               
3684                      layerViews.put(page, BUILD_AND_SET_LAYER);                                                    
3685                                                                                                                    
3686                      ObjectAnimator pageDrift = LauncherAnimUtils.ofFloat(page, "translationY",                    
3687                              0, yDrift);                                                                           
3688                      page.setTranslationY(0);                                                                      
3689                      pageDrift.setDuration(revealDuration - SINGLE_FRAME_DELAY);                                   
3690                      pageDrift.setInterpolator(decelerateInterpolator);                                            
3691                      pageDrift.setStartDelay(itemsAlphaStagger + SINGLE_FRAME_DELAY);                              
3692                      mStateAnimation.play(pageDrift);                                                              
3693                                                                                                                    
3694                      page.setAlpha(1f);                                                                            
3695                      ObjectAnimator itemsAlpha = LauncherAnimUtils.ofFloat(page, "alpha", 1f, 0f);                 
3696                      itemsAlpha.setDuration(100);                                                                  
3697                      itemsAlpha.setInterpolator(decelerateInterpolator);                                           
3698                      mStateAnimation.play(itemsAlpha);                                                             
3699                  }                                                                                                 
3700                                                                                                                    
3701                  View pageIndicators = fromView.findViewById(R.id.apps_customize_page_indicator);                  
3702                  pageIndicators.setAlpha(1f);                                                                      
3703                  ObjectAnimator indicatorsAlpha =                                                                  
3704                          LauncherAnimUtils.ofFloat(pageIndicators, "alpha", 0f);                                   
3705                  indicatorsAlpha.setDuration(revealDuration);                                                      
3706                  indicatorsAlpha.setInterpolator(new DecelerateInterpolator(1.5f));                                
3707                  mStateAnimation.play(indicatorsAlpha);                                                            
3708                                                                                                                    
3709                  width = revealView.getMeasuredWidth();                                                            
3710                                                                                                                    
3711                  if (material) {                                                                                   
3712                      if (!isWidgetTray) {                                                                          
3713                          allAppsButton.setVisibility(View.INVISIBLE);                                              
3714                      }                                                                                             
3715                      int allAppsButtonSize = LauncherAppState.getInstance().                                       
3716                              getDynamicGrid().getDeviceProfile().allAppsButtonVisualSize;                          
3717                      float finalRadius = isWidgetTray ? 0 : allAppsButtonSize / 2;                                 
3718                      Animator reveal =                                                                             
3719                              LauncherAnimUtils.createCircularReveal(revealView, width / 2,                         
3720                                      height / 2, revealRadius, finalRadius);                                       
3721                      reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));                                
3722                      reveal.setDuration(revealDuration);                                                           
3723                      reveal.setStartDelay(itemsAlphaStagger);                                                      
3724                                                                                                                    
3725                      reveal.addListener(new AnimatorListenerAdapter() {                                            
3726                          public void onAnimationEnd(Animator animation) {                                          
3727                              revealView.setVisibility(View.INVISIBLE);                                             
3728                              if (!isWidgetTray) {                                                                  
3729                                  allAppsButton.setVisibility(View.VISIBLE);                                        
3730                              }                                                                                     
3731                          }                                                                                         
3732                      });                                                                                           
3733                                                                                                                    
3734                      mStateAnimation.play(reveal);                                                                 
3735                  }                                                                                                 
3736                                                                                                                    
3737                  dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                    
3738                  dispatchOnLauncherTransitionPrepare(toView, animated, true);                                      
3739                  mAppsCustomizeContent.stopScrolling();                                                            
3740              }                                                                                                     
3741                                                                                                                    
3742              mStateAnimation.addListener(new AnimatorListenerAdapter() {                                           
3743                  @Override                                                                                         
3744                  public void onAnimationEnd(Animator animation) {                                                  
3745                      fromView.setVisibility(View.GONE);                                                            
3746                      dispatchOnLauncherTransitionEnd(fromView, animated, true);                                    
3747                      dispatchOnLauncherTransitionEnd(toView, animated, true);                                      
3748                      if (onCompleteRunnable != null) {                                                             
3749                          onCompleteRunnable.run();                                                                 
3750                      }                                                                                             
3751                                                                                                                    
3752                      for (View v : layerViews.keySet()) {                                                          
3753                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3754                              v.setLayerType(View.LAYER_TYPE_NONE, null);                                           
3755                          }                                                                                         
3756                      }                                                                                             
3757                                                                                                                    
3758                      content.setPageBackgroundsVisible(true);                                                      
3759                      // Unhide side pages                                                                          
3760                      int count = content.getChildCount();                                                          
3761                      for (int i = 0; i < count; i++) {                                                             
3762                          View child = content.getChildAt(i);                                                       
3763                          child.setVisibility(View.VISIBLE);                                                        
3764                      }                                                                                             
3765                                                                                                                    
3766                      // Reset page transforms                                                                      
3767                      if (page != null) {                                                                           
3768                          page.setTranslationX(0);                                                                  
3769                          page.setTranslationY(0);                                                                  
3770                          page.setAlpha(1);                                                                         
3771                      }                                                                                             
3772                      content.setCurrentPage(content.getNextPage());                                                
3773                                                                                                                    
3774                      mAppsCustomizeContent.updateCurrentPageScroll();                                              
3775                                                                                                                    
3776                      // This can hold unnecessary references to views.                                             
3777                      mStateAnimation = null;                                                                       
3778                  }                                                                                                 
3779              });                                                                                                   
3780                                                                                                                    
3781              final AnimatorSet stateAnimation = mStateAnimation;                                                   
3782              final Runnable startAnimRunnable = new Runnable() {                                                   
3783                  public void run() {                                                                               
3784                      // Check that mStateAnimation hasn't changed while                                            
3785                      // we waited for a layout/draw pass                                                           
3786                      if (mStateAnimation != stateAnimation)                                                        
3787                          return;                                                                                   
3788                      dispatchOnLauncherTransitionStart(fromView, animated, false);                                 
3789                      dispatchOnLauncherTransitionStart(toView, animated, false);                                   
3790                                                                                                                    
3791                      for (View v : layerViews.keySet()) {                                                          
3792                          if (layerViews.get(v) == BUILD_AND_SET_LAYER) {                                           
3793                              v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                                       
3794                          }                                                                                         
3795                      }                                                                                             
3796                                                                                                                    
3797                      if (Utilities.isLmpOrAbove()) {                                                               
3798                          for (View v : layerViews.keySet()) {                                                      
3799                              if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();                              
3800                          }                                                                                         
3801                      }                                                                                             
3802                      mStateAnimation.start();                                                                      
3803                  }                                                                                                 
3804              };                                                                                                    
3805              fromView.post(startAnimRunnable);                                                                     
3806          } else {                                                                                                  
3807              fromView.setVisibility(View.GONE);                                                                    
3808              dispatchOnLauncherTransitionPrepare(fromView, animated, true);                                        
3809              dispatchOnLauncherTransitionStart(fromView, animated, true);                                          
3810              dispatchOnLauncherTransitionEnd(fromView, animated, true);                                            
3811              dispatchOnLauncherTransitionPrepare(toView, animated, true);                                          
3812              dispatchOnLauncherTransitionStart(toView, animated, true);                                            
3813              dispatchOnLauncherTransitionEnd(toView, animated, true);                                              
3814          }                                                                                                         
3815      }                                                                                                             
3816                                                                                                                    
3817      @Override                                                                                                     
3818      public void onTrimMemory(int level) {                                                                         
3819          super.onTrimMemory(level);                                                                                
3820          if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {                                                 
3821              // The widget preview db can result in holding onto over                                              
3822              // 3MB of memory for caching which isn't necessary.                                                   
3823              SQLiteDatabase.releaseMemory();                                                                       
3824                                                                                                                    
3825              // This clears all widget bitmaps from the widget tray                                                
3826              if (mAppsCustomizeTabHost != null) {                                                                  
3827                  mAppsCustomizeTabHost.trimMemory();                                                               
3828              }                                                                                                     

3829          }                                                                                                         
3830          if (mLauncherCallbacks != null) {                                                                         
3831              mLauncherCallbacks.onTrimMemory(level);                                                               
3832          }                                                                                                         
3833      }                                                                                                             
3834                                                                                                                    








3835      protected void showWorkspace(boolean animated) {                                                              
3836          showWorkspace(animated, null);                                                                            
3837      }                                                                                                             
3838                                                                                                                    
3839      protected void showWorkspace() {                                                                              
3840          showWorkspace(true);                                                                                      
3841      }                                                                                                             
3842                                                                                                                    
3843      void showWorkspace(boolean animated, Runnable onCompleteRunnable) {                                           
3844          if (mState != State.WORKSPACE || mWorkspace.getState() != Workspace.State.NORMAL) {                       



3845              boolean wasInSpringLoadedMode = (mState != State.WORKSPACE);                                          
3846              mWorkspace.setVisibility(View.VISIBLE);                                                               
3847              hideAppsCustomizeHelper(Workspace.State.NORMAL, animated, false, onCompleteRunnable);                 


3848                                                                                                                    
3849              // Show the search bar (only animate if we were showing the drop target bar in spring                 
3850              // loaded mode)                                                                                       
3851              if (mSearchDropTargetBar != null) {                                                                   
3852                  mSearchDropTargetBar.showSearchBar(animated && wasInSpringLoadedMode);                            
3853              }                                                                                                     
3854                                                                                                                    
3855              // Set focus to the AppsCustomize button                                                              
3856              if (mAllAppsButton != null) {                                                                         
3857                  mAllAppsButton.requestFocus();                                                                    
3858              }                                                                                                     
3859          }                                                                                                         
3860                                                                                                                    
3861          // Change the state *after* we've called all the transition code                                          
3862          mState = State.WORKSPACE;                                                                                 
3863                                                                                                                    
3864          // Resume the auto-advance of widgets                                                                     
3865          mUserPresent = true;                                                                                      
3866          updateRunning();                                                                                          









































































3867                                                                                                                    
3868          // Send an accessibility event to announce the context change                                             
3869          getWindow().getDecorView()                                                                                
3870                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3871                                                                                                                    
3872          onWorkspaceShown(animated);                                                                               
3873      }                                                                                                             
3874                                                                                                                    
3875      void showOverviewMode(boolean animated) {                                                                     
3876          mWorkspace.setVisibility(View.VISIBLE);                                                                   
3877          hideAppsCustomizeHelper(Workspace.State.OVERVIEW, animated, false, null);                                 
3878          mState = State.WORKSPACE;                                                                                 
3879          onWorkspaceShown(animated);                                                                               
3880      }                                                                                                             
3881                                                                                                                    
3882      public void onWorkspaceShown(boolean animated) {                                                              
3883      }                                                                                                             
3884                                                                                                                    
3885      void showAllApps(boolean animated, AppsCustomizePagedView.ContentType contentType,                            
3886                       boolean resetPageToZero) {                                                                   
3887          if (mState != State.WORKSPACE) return;                                                                    
3888                                                                                                                    
3889          if (resetPageToZero) {                                                                                    
3890              mAppsCustomizeTabHost.reset();                                                                        
3891          }                                                                                                         
3892          showAppsCustomizeHelper(animated, false, contentType);                                                    
3893          mAppsCustomizeTabHost.post(new Runnable() {                                                               
3894              @Override                                                                                             
3895              public void run() {                                                                                   
3896                  // We post this in-case the all apps view isn't yet constructed.                                  
3897                  mAppsCustomizeTabHost.requestFocus();                                                             
3898              }                                                                                                     
3899          });                                                                                                       
3900                                                                                                                    
3901          // Change the state *after* we've called all the transition code                                          
3902          mState = State.APPS_CUSTOMIZE;                                                                            
3903                                                                                                                    
3904          // Pause the auto-advance of widgets until we are out of AllApps                                          
3905          mUserPresent = false;                                                                                     
3906          updateRunning();                                                                                          
3907          closeFolder();                                                                                            
3908                                                                                                                    
3909          // Send an accessibility event to announce the context change                                             
3910          getWindow().getDecorView()                                                                                
3911                  .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);                            
3912      }                                                                                                             
3913                                                                                                                    
3914      void enterSpringLoadedDragMode() {                                                                            
3915          if (isAllAppsVisible()) {                                                                                 
3916              hideAppsCustomizeHelper(Workspace.State.SPRING_LOADED, true, true, null);                             
3917              mState = State.APPS_CUSTOMIZE_SPRING_LOADED;                                                          
3918          }                                                                                                         
3919      }                                                                                                             
3920                                                                                                                    
3921      void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,                                 
















3922              final Runnable onCompleteRunnable) {                                                                  
3923          if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;                                                 

3924                                                                                                                    
3925          mHandler.postDelayed(new Runnable() {                                                                     
3926              @Override                                                                                             
3927              public void run() {                                                                                   
3928                  if (successfulDrop) {                                                                             


3929                      // Before we show workspace, hide all apps again because                                      
3930                      // exitSpringLoadedDragMode made it visible. This is a bit hacky; we should                   
3931                      // clean up our state transition functions                                                    
3932                      mAppsCustomizeTabHost.setVisibility(View.GONE);                                               

3933                      showWorkspace(true, onCompleteRunnable);                                                      
3934                  } else {                                                                                          
3935                      exitSpringLoadedDragMode();                                                                   
3936                  }                                                                                                 
3937              }                                                                                                     
3938          }, delay);                                                                                                
3939      }                                                                                                             
3940                                                                                                                    
3941      void exitSpringLoadedDragMode() {                                                                             
3942          if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {                                                       
3943              final boolean animated = true;                                                                        
3944              final boolean springLoaded = true;                                                                    
3945              showAppsCustomizeHelper(animated, springLoaded);                                                      
3946              mState = State.APPS_CUSTOMIZE;                                                                        






3947          }                                                                                                         
3948          // Otherwise, we are not in spring loaded mode, so don't do anything.                                     
3949      }                                                                                                             
3950                                                                                                                    
3951      void lockAllApps() {                                                                                          
3952          // TODO                                                                                                   
3953      }                                                                                                             
3954                                                                                                                    
3955      void unlockAllApps() {                                                                                        
3956          // TODO                                                                                                   
3957      }                                                                                                             
3958                                                                                                                    
3959      protected void disableVoiceButtonProxy(boolean disable) {                                                     
3960          // NO-OP                                                                                                  
3961      }                                                                                                             
3962                                                                                                                    
3963      public View getQsbBar() {                                                                                     

3964          if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {                                  
3965              return mLauncherCallbacks.getQsbBar();                                                                
3966          }                                                                                                         
3967                                                                                                                    
3968          if (mQsb == null) {                                                                                       
3969              AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);                       
3970              if (searchProvider == null) {                                                                         
3971                  return null;                                                                                      
3972              }                                                                                                     
3973                                                                                                                    
3974              Bundle opts = new Bundle();                                                                           
3975              opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,                                          
3976                      AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);                                             
3977                                                                                                                    
3978              SharedPreferences sp = getSharedPreferences(                                                          
3979                      LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);                                    
3980              int widgetId = sp.getInt(QSB_WIDGET_ID, -1);                                                          
3981              AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);                      
3982              if (!searchProvider.provider.flattenToString().equals(                                                
3983                      sp.getString(QSB_WIDGET_PROVIDER, null))                                                      
3984                      || (widgetInfo == null)                                                                       
3985                      || !widgetInfo.provider.equals(searchProvider.provider)) {                                    
3986                  // A valid widget is not already bound.                                                           
3987                  if (widgetId > -1) {                                                                              
3988                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
3989                      widgetId = -1;                                                                                
3990                  }                                                                                                 
3991                                                                                                                    
3992                  // Try to bind a new widget                                                                       
3993                  widgetId = mAppWidgetHost.allocateAppWidgetId();                                                  
3994                                                                                                                    
3995                  if (!AppWidgetManagerCompat.getInstance(this)                                                     
3996                          .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {                              
3997                      mAppWidgetHost.deleteAppWidgetId(widgetId);                                                   
3998                      widgetId = -1;                                                                                
3999                  }                                                                                                 
4000                                                                                                                    
4001                  sp.edit()                                                                                         
4002                      .putInt(QSB_WIDGET_ID, widgetId)                                                              
4003                      .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())                    
4004                      .commit();                                                                                    
4005              }                                                                                                     
4006                                                                                                                    
4007              if (widgetId != -1) {                                                                                 
4008                  mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                                 
4009                  mQsb.updateAppWidgetOptions(opts);                                                                
4010                  mQsb.setPadding(0, 0, 0, 0);                                                                      
4011                  mSearchDropTargetBar.addView(mQsb);                                                               

4012              }                                                                                                     
4013          }                                                                                                         
4014          return mQsb;                                                                                              









4015      }                                                                                                             
4016                                                                                                                    
4017      @Override                                                                                                     
4018      public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {                                 
4019          final boolean result = super.dispatchPopulateAccessibilityEvent(event);                                   
4020          final List<CharSequence> text = event.getText();                                                          
4021          text.clear();                                                                                             
4022          // Populate event with a fake title based on the current state.                                           
4023          if (mState == State.APPS_CUSTOMIZE) {                                                                     
4024              text.add(mAppsCustomizeTabHost.getContentTag());                                                      




4025          } else {                                                                                                  
4026              text.add(getString(R.string.all_apps_home_button_label));                                             
4027          }                                                                                                         
4028          return result;                                                                                            
4029      }                                                                                                             
4030                                                                                                                    
4031      /**                                                                                                           
4032       * Receives notifications when system dialogs are to be closed.                                               
4033       */                                                                                                           
4034      private class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {                                    

4035          @Override                                                                                                 
4036          public void onReceive(Context context, Intent intent) {                                                   
4037              closeSystemDialogs();                                                                                 
4038          }                                                                                                         
4039      }                                                                                                             
4040                                                                                                                    
4041      /**                                                                                                           
4042       * Receives notifications whenever the appwidgets are reset.                                                  
4043       */                                                                                                           
4044      private class AppWidgetResetObserver extends ContentObserver {                                                
4045          public AppWidgetResetObserver() {                                                                         
4046              super(new Handler());                                                                                 
4047          }                                                                                                         
4048                                                                                                                    
4049          @Override                                                                                                 
4050          public void onChange(boolean selfChange) {                                                                
4051              onAppWidgetReset();                                                                                   
4052          }                                                                                                         
4053      }                                                                                                             
4054                                                                                                                    
4055      /**                                                                                                           
4056       * If the activity is currently paused, signal that we need to run the passed Runnable                        
4057       * in onResume.                                                                                               
4058       *                                                                                                            
4059       * This needs to be called from incoming places where resources might have been loaded                        
4060       * while we are paused.  That is becaues the Configuration might be wrong                                     
4061       * when we're not running, and if it comes back to what it was when we                                        
4062       * were paused, we are not restarted.                                                                         
4063       *                                                                                                            
4064       * Implementation of the method from LauncherModel.Callbacks.                                                 
4065       *                                                                                                            
4066       * @return true if we are currently paused.  The caller might be able to                                      
4067       * skip some work in that case since we will come back again.                                                 
4068       */                                                                                                           
4069      private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {                              
4070          if (mPaused) {                                                                                            
4071              Log.i(TAG, "Deferring update until onResume");                                                        
4072              if (deletePreviousRunnables) {                                                                        
4073                  while (mBindOnResumeCallbacks.remove(run)) {                                                      
4074                  }                                                                                                 
4075              }                                                                                                     
4076              mBindOnResumeCallbacks.add(run);                                                                      
4077              return true;                                                                                          
4078          } else {                                                                                                  
4079              return false;                                                                                         
4080          }                                                                                                         
4081      }                                                                                                             
4082                                                                                                                    
4083      private boolean waitUntilResume(Runnable run) {                                                               
4084          return waitUntilResume(run, false);                                                                       
4085      }                                                                                                             
4086                                                                                                                    
4087      public void addOnResumeCallback(Runnable run) {                                                               
4088          mOnResumeCallbacks.add(run);                                                                              
4089      }                                                                                                             
4090                                                                                                                    
4091      /**                                                                                                           
4092       * If the activity is currently paused, signal that we need to re-run the loader                              
4093       * in onResume.                                                                                               
4094       *                                                                                                            
4095       * This needs to be called from incoming places where resources might have been loaded                        
4096       * while we are paused.  That is becaues the Configuration might be wrong                                     
4097       * when we're not running, and if it comes back to what it was when we                                        
4098       * were paused, we are not restarted.                                                                         
4099       *                                                                                                            
4100       * Implementation of the method from LauncherModel.Callbacks.                                                 
4101       *                                                                                                            
4102       * @return true if we are currently paused.  The caller might be able to                                      
4103       * skip some work in that case since we will come back again.                                                 
4104       */                                                                                                           
4105      public boolean setLoadOnResume() {                                                                            
4106          if (mPaused) {                                                                                            
4107              Log.i(TAG, "setLoadOnResume");                                                                        
4108              mOnResumeNeedsLoad = true;                                                                            
4109              return true;                                                                                          
4110          } else {                                                                                                  
4111              return false;                                                                                         
4112          }                                                                                                         
4113      }                                                                                                             
4114                                                                                                                    
4115      /**                                                                                                           
4116       * Implementation of the method from LauncherModel.Callbacks.                                                 
4117       */                                                                                                           
4118      public int getCurrentWorkspaceScreen() {                                                                      
4119          if (mWorkspace != null) {                                                                                 
4120              return mWorkspace.getCurrentPage();                                                                   
4121          } else {                                                                                                  
4122              return SCREEN_COUNT / 2;                                                                              
4123          }                                                                                                         
4124      }                                                                                                             
4125                                                                                                                    
4126      /**                                                                                                           
4127       * Refreshes the shortcuts shown on the workspace.                                                            
4128       *                                                                                                            
4129       * Implementation of the method from LauncherModel.Callbacks.                                                 
4130       */                                                                                                           
4131      public void startBinding() {                                                                                  
4132          setWorkspaceLoading(true);                                                                                
4133                                                                                                                    
4134          // If we're starting binding all over again, clear any bind calls we'd postponed in                       
4135          // the past (see waitUntilResume) -- we don't need them since we're starting binding                      
4136          // from scratch again                                                                                     
4137          mBindOnResumeCallbacks.clear();                                                                           
4138                                                                                                                    
4139          // Clear the workspace because it's going to be rebound                                                   
4140          mWorkspace.clearDropTargets();                                                                            
4141          mWorkspace.removeAllWorkspaceScreens();                                                                   
4142                                                                                                                    
4143          mWidgetsToAdvance.clear();                                                                                
4144          if (mHotseat != null) {                                                                                   
4145              mHotseat.resetLayout();                                                                               
4146          }                                                                                                         
4147      }                                                                                                             
4148                                                                                                                    
4149      @Override                                                                                                     
4150      public void bindScreens(ArrayList<Long> orderedScreenIds) {                                                   
4151          bindAddScreens(orderedScreenIds);                                                                         
4152                                                                                                                    
4153          // If there are no screens, we need to have an empty screen                                               
4154          if (orderedScreenIds.size() == 0) {                                                                       
4155              mWorkspace.addExtraEmptyScreen();                                                                     
4156          }                                                                                                         
4157                                                                                                                    
4158          // Create the custom content page (this call updates mDefaultScreen which calls                           
4159          // setCurrentPage() so ensure that all pages are added before calling this).                              
4160          if (hasCustomContentToLeft()) {                                                                           
4161              mWorkspace.createCustomContentContainer();                                                            
4162              populateCustomContentContainer();                                                                     
4163          }                                                                                                         
4164      }                                                                                                             
4165                                                                                                                    
4166      @Override                                                                                                     
4167      public void bindAddScreens(ArrayList<Long> orderedScreenIds) {                                                
4168          // Log to disk                                                                                            
4169          Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);                                            
4170          Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +                                              
4171                  TextUtils.join(", ", orderedScreenIds), true);                                                    
4172          int count = orderedScreenIds.size();                                                                      
4173          for (int i = 0; i < count; i++) {                                                                         
4174              mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));                        
4175          }                                                                                                         
4176      }                                                                                                             
4177                                                                                                                    
4178      @Override                                                                                                     
4179      public void bindAddPendingItem(final PendingAddItemInfo info, final long container,                           
4180              final long screenId, final int[] cell, final int spanX, final int spanY) {                            
4181          showWorkspace(true, new Runnable() {                                                                      
4182                                                                                                                    
4183              @Override                                                                                             
4184              public void run() {                                                                                   
4185                  mWorkspace.snapToPage(mWorkspace.getPageIndexForScreenId(screenId));                              
4186                  addPendingItem(info, container, screenId, cell, spanX, spanY);                                    
4187              }                                                                                                     
4188          });                                                                                                       
4189      }                                                                                                             
4190                                                                                                                    
4191      private boolean shouldShowWeightWatcher() {                                                                   
4192          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4193          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4194          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, SHOW_WEIGHT_WATCHER_DEFAULT);                           
4195                                                                                                                    
4196          return show;                                                                                              
4197      }                                                                                                             
4198                                                                                                                    
4199      private void toggleShowWeightWatcher() {                                                                      
4200          String spKey = LauncherAppState.getSharedPreferencesKey();                                                
4201          SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);                                 
4202          boolean show = sp.getBoolean(SHOW_WEIGHT_WATCHER, true);                                                  
4203                                                                                                                    
4204          show = !show;                                                                                             
4205                                                                                                                    
4206          SharedPreferences.Editor editor = sp.edit();                                                              
4207          editor.putBoolean(SHOW_WEIGHT_WATCHER, show);                                                             
4208          editor.commit();                                                                                          
4209                                                                                                                    
4210          if (mWeightWatcher != null) {                                                                             
4211              mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);                                        
4212          }                                                                                                         
4213      }                                                                                                             
4214                                                                                                                    
4215      public void bindAppsAdded(final ArrayList<Long> newScreens,                                                   
4216                                final ArrayList<ItemInfo> addNotAnimated,                                           
4217                                final ArrayList<ItemInfo> addAnimated,                                              
4218                                final ArrayList<AppInfo> addedApps) {                                               
4219          Runnable r = new Runnable() {                                                                             
4220              public void run() {                                                                                   
4221                  bindAppsAdded(newScreens, addNotAnimated, addAnimated, addedApps);                                
4222              }                                                                                                     
4223          };                                                                                                        
4224          if (waitUntilResume(r)) {                                                                                 
4225              return;                                                                                               
4226          }                                                                                                         
4227                                                                                                                    
4228          // Add the new screens                                                                                    
4229          if (newScreens != null) {                                                                                 
4230              bindAddScreens(newScreens);                                                                           
4231          }                                                                                                         
4232                                                                                                                    
4233          // We add the items without animation on non-visible pages, and with                                      
4234          // animations on the new page (which we will try and snap to).                                            
4235          if (addNotAnimated != null && !addNotAnimated.isEmpty()) {                                                
4236              bindItems(addNotAnimated, 0,                                                                          
4237                      addNotAnimated.size(), false);                                                                
4238          }                                                                                                         
4239          if (addAnimated != null && !addAnimated.isEmpty()) {                                                      
4240              bindItems(addAnimated, 0,                                                                             
4241                      addAnimated.size(), true);                                                                    
4242          }                                                                                                         
4243                                                                                                                    
4244          // Remove the extra empty screen                                                                          
4245          mWorkspace.removeExtraEmptyScreen(false, false);                                                          
4246                                                                                                                    
4247          if (!LauncherAppState.isDisableAllApps() &&                                                               
4248                  addedApps != null && mAppsCustomizeContent != null) {                                             
4249              mAppsCustomizeContent.addApps(addedApps);                                                             


4250          }                                                                                                         
4251      }                                                                                                             
4252                                                                                                                    
4253      /**                                                                                                           
4254       * Bind the items start-end from the list.                                                                    
4255       *                                                                                                            
4256       * Implementation of the method from LauncherModel.Callbacks.                                                 
4257       */                                                                                                           
4258      public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,                    
4259                            final boolean forceAnimateIcons) {                                                      
4260          Runnable r = new Runnable() {                                                                             
4261              public void run() {                                                                                   
4262                  bindItems(shortcuts, start, end, forceAnimateIcons);                                              
4263              }                                                                                                     
4264          };                                                                                                        
4265          if (waitUntilResume(r)) {                                                                                 
4266              return;                                                                                               
4267          }                                                                                                         
4268                                                                                                                    
4269          // Get the list of added shortcuts and intersect them with the set of shortcuts here                      
4270          final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();                                           
4271          final Collection<Animator> bounceAnims = new ArrayList<Animator>();                                       
4272          final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();                               
4273          Workspace workspace = mWorkspace;                                                                         
4274          long newShortcutsScreenId = -1;                                                                           
4275          for (int i = start; i < end; i++) {                                                                       
4276              final ItemInfo item = shortcuts.get(i);                                                               
4277                                                                                                                    
4278              // Short circuit if we are loading dock items for a configuration which has no dock                   
4279              if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&                                 
4280                      mHotseat == null) {                                                                           
4281                  continue;                                                                                         
4282              }                                                                                                     
4283                                                                                                                    
4284              switch (item.itemType) {                                                                              
4285                  case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:                                            
4286                  case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:                                               
4287                      ShortcutInfo info = (ShortcutInfo) item;                                                      
4288                      View shortcut = createShortcut(info);                                                         
4289                                                                                                                    
4290                      /*                                                                                            
4291                       * TODO: FIX collision case                                                                   
4292                       */                                                                                           
4293                      if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {                         
4294                          CellLayout cl = mWorkspace.getScreenWithId(item.screenId);                                
4295                          if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {                                
4296                              View v = cl.getChildAt(item.cellX, item.cellY);                                       
4297                              Object tag = v.getTag();                                                              
4298                              String desc = "Collision while binding workspace item: " + item                       
4299                                      + ". Collides with " + tag;                                                   
4300                              if (LauncherAppState.isDogfoodBuild()) {                                              
4301                                  throw (new RuntimeException(desc));                                               
4302                              } else {                                                                              
4303                                  Log.d(TAG, desc);                                                                 
4304                              }                                                                                     
4305                          }                                                                                         
4306                      }                                                                                             
4307                                                                                                                    
4308                      workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,            
4309                              item.cellY, 1, 1);                                                                    
4310                      if (animateIcons) {                                                                           
4311                          // Animate all the applications up now                                                    
4312                          shortcut.setAlpha(0f);                                                                    
4313                          shortcut.setScaleX(0f);                                                                   
4314                          shortcut.setScaleY(0f);                                                                   
4315                          bounceAnims.add(createNewAppBounceAnimation(shortcut, i));                                
4316                          newShortcutsScreenId = item.screenId;                                                     
4317                      }                                                                                             
4318                      break;                                                                                        
4319                  case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:                                                 
4320                      FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,                         
4321                              (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),                         
4322                              (FolderInfo) item, mIconCache);                                                       
4323                      workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,           
4324                              item.cellY, 1, 1);                                                                    
4325                      break;                                                                                        
4326                  default:                                                                                          
4327                      throw new RuntimeException("Invalid Item Type");                                              
4328              }                                                                                                     
4329          }                                                                                                         
4330                                                                                                                    
4331          if (animateIcons) {                                                                                       
4332              // Animate to the correct page                                                                        
4333              if (newShortcutsScreenId > -1) {                                                                      
4334                  long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());              
4335                  final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);              
4336                  final Runnable startBounceAnimRunnable = new Runnable() {                                         
4337                      public void run() {                                                                           
4338                          anim.playTogether(bounceAnims);                                                           
4339                          anim.start();                                                                             
4340                      }                                                                                             
4341                  };                                                                                                
4342                  if (newShortcutsScreenId != currentScreenId) {                                                    
4343                      // We post the animation slightly delayed to prevent slowdowns                                
4344                      // when we are loading right after we return to launcher.                                     
4345                      mWorkspace.postDelayed(new Runnable() {                                                       
4346                          public void run() {                                                                       
4347                              if (mWorkspace != null) {                                                             
4348                                  mWorkspace.snapToPage(newScreenIndex);                                            
4349                                  mWorkspace.postDelayed(startBounceAnimRunnable,                                   
4350                                          NEW_APPS_ANIMATION_DELAY);                                                
4351                              }                                                                                     
4352                          }                                                                                         
4353                      }, NEW_APPS_PAGE_MOVE_DELAY);                                                                 
4354                  } else {                                                                                          
4355                      mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);                    
4356                  }                                                                                                 
4357              }                                                                                                     
4358          }                                                                                                         
4359          workspace.requestLayout();                                                                                
4360      }                                                                                                             
4361                                                                                                                    
4362      /**                                                                                                           
4363       * Implementation of the method from LauncherModel.Callbacks.                                                 
4364       */                                                                                                           
4365      public void bindFolders(final HashMap<Long, FolderInfo> folders) {                                            
4366          Runnable r = new Runnable() {                                                                             
4367              public void run() {                                                                                   
4368                  bindFolders(folders);                                                                             
4369              }                                                                                                     
4370          };                                                                                                        
4371          if (waitUntilResume(r)) {                                                                                 
4372              return;                                                                                               
4373          }                                                                                                         
4374          sFolders.clear();                                                                                         
4375          sFolders.putAll(folders);                                                                                 
4376      }                                                                                                             
4377                                                                                                                    
4378      /**                                                                                                           
4379       * Add the views for a widget to the workspace.                                                               
4380       *                                                                                                            
4381       * Implementation of the method from LauncherModel.Callbacks.                                                 
4382       */                                                                                                           
4383      public void bindAppWidget(final LauncherAppWidgetInfo item) {                                                 
4384          Runnable r = new Runnable() {                                                                             
4385              public void run() {                                                                                   
4386                  bindAppWidget(item);                                                                              
4387              }                                                                                                     
4388          };                                                                                                        
4389          if (waitUntilResume(r)) {                                                                                 
4390              return;                                                                                               
4391          }                                                                                                         
4392                                                                                                                    
4393          final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;                                        
4394          if (DEBUG_WIDGETS) {                                                                                      
4395              Log.d(TAG, "bindAppWidget: " + item);                                                                 
4396          }                                                                                                         
4397          final Workspace workspace = mWorkspace;                                                                   
4398                                                                                                                    
4399          LauncherAppWidgetProviderInfo appWidgetInfo =                                                             
4400                  LauncherModel.getProviderInfo(this, item.providerName, item.user);                                
4401                                                                                                                    
4402          if (!mIsSafeModeEnabled                                                                                   
4403                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)                    
4404                  && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {                       
4405              if (appWidgetInfo == null) {                                                                          
4406                  if (DEBUG_WIDGETS) {                                                                              
4407                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4408                              + " belongs to component " + item.providerName                                        
4409                              + ", as the povider is null");                                                        
4410                  }                                                                                                 
4411                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4412                  return;                                                                                           
4413              }                                                                                                     
4414              // Note: This assumes that the id remap broadcast is received before this step.                       
4415              // If that is not the case, the id remap will be ignored and user may see the                         
4416              // click to setup view.                                                                               
4417              PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(appWidgetInfo, null);                     
4418              pendingInfo.spanX = item.spanX;                                                                       
4419              pendingInfo.spanY = item.spanY;                                                                       
4420              pendingInfo.minSpanX = item.minSpanX;                                                                 
4421              pendingInfo.minSpanY = item.minSpanY;                                                                 
4422              Bundle options =                                                                                      
4423                      AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);                         


4424                                                                                                                    
4425              int newWidgetId = mAppWidgetHost.allocateAppWidgetId();                                               
4426              boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(                                         
4427                      newWidgetId, appWidgetInfo, options);                                                         
4428                                                                                                                    
4429              // TODO consider showing a permission dialog when the widget is clicked.                              
4430              if (!success) {                                                                                       
4431                  mAppWidgetHost.deleteAppWidgetId(newWidgetId);                                                    
4432                  if (DEBUG_WIDGETS) {                                                                              
4433                      Log.d(TAG, "Removing restored widget: id=" + item.appWidgetId                                 
4434                              + " belongs to component " + item.providerName                                        
4435                              + ", as the launcher is unable to bing a new widget id");                             
4436                  }                                                                                                 
4437                  LauncherModel.deleteItemFromDatabase(this, item);                                                 
4438                  return;                                                                                           
4439              }                                                                                                     
4440                                                                                                                    
4441              item.appWidgetId = newWidgetId;                                                                       
4442                                                                                                                    
4443              // If the widget has a configure activity, it is still needs to set it up, otherwise                  
4444              // the widget is ready to go.                                                                         
4445              item.restoreStatus = (appWidgetInfo.configure == null)                                                
4446                      ? LauncherAppWidgetInfo.RESTORE_COMPLETED                                                     
4447                      : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;                                                    
4448                                                                                                                    
4449              LauncherModel.updateItemInDatabase(this, item);                                                       
4450          }                                                                                                         
4451                                                                                                                    
4452          if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {               
4453              final int appWidgetId = item.appWidgetId;                                                             
4454              if (DEBUG_WIDGETS) {                                                                                  
4455                  Log.d(TAG, "bindAppWidget: id=" + item.appWidgetId + " belongs to component "                     
4456                          + appWidgetInfo.provider);                                                                
4457              }                                                                                                     
4458                                                                                                                    
4459              item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);                          
4460          } else {                                                                                                  
4461              appWidgetInfo = null;                                                                                 
4462              PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,                              
4463                      mIsSafeModeEnabled);                                                                          
4464              view.updateIcon(mIconCache);                                                                          
4465              item.hostView = view;                                                                                 
4466              item.hostView.updateAppWidget(null);                                                                  
4467              item.hostView.setOnClickListener(this);                                                               
4468          }                                                                                                         
4469                                                                                                                    
4470          item.hostView.setTag(item);                                                                               
4471          item.onBindAppWidget(this);                                                                               
4472                                                                                                                    
4473          workspace.addInScreen(item.hostView, item.container, item.screenId, item.cellX,                           
4474                  item.cellY, item.spanX, item.spanY, false);                                                       
4475          if (!item.isCustomWidget()) {                                                                             
4476              addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);                                         
4477          }                                                                                                         
4478                                                                                                                    
4479          workspace.requestLayout();                                                                                
4480                                                                                                                    
4481          if (DEBUG_WIDGETS) {                                                                                      
4482              Log.d(TAG, "bound widget id="+item.appWidgetId+" in "                                                 
4483                      + (SystemClock.uptimeMillis()-start) + "ms");                                                 
4484          }                                                                                                         
4485      }                                                                                                             
4486                                                                                                                    
4487      /**                                                                                                           
4488       * Restores a pending widget.                                                                                 
4489       *                                                                                                            
4490       * @param appWidgetId The app widget id                                                                       
4491       * @param cellInfo The position on screen where to create the widget.                                         
4492       */                                                                                                           
4493      private void completeRestoreAppWidget(final int appWidgetId) {                                                
4494          LauncherAppWidgetHostView view = mWorkspace.getWidgetForAppWidgetId(appWidgetId);                         
4495          if ((view == null) || !(view instanceof PendingAppWidgetHostView)) {                                      
4496              Log.e(TAG, "Widget update called, when the widget no longer exists.");                                
4497              return;                                                                                               
4498          }                                                                                                         
4499                                                                                                                    
4500          LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();                                       
4501          info.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;                                             
4502                                                                                                                    
4503          mWorkspace.reinflateWidgetsIfNecessary();                                                                 
4504          LauncherModel.updateItemInDatabase(this, info);                                                           
4505      }                                                                                                             
4506                                                                                                                    
4507      public void onPageBoundSynchronously(int page) {                                                              
4508          mSynchronouslyBoundPages.add(page);                                                                       
4509      }                                                                                                             
4510                                                                                                                    
4511      /**                                                                                                           
4512       * Callback saying that there aren't any more items to bind.                                                  
4513       *                                                                                                            
4514       * Implementation of the method from LauncherModel.Callbacks.                                                 
4515       */                                                                                                           
4516      public void finishBindingItems(final boolean upgradePath) {                                                   

4517          Runnable r = new Runnable() {                                                                             
4518              public void run() {                                                                                   
4519                  finishBindingItems(upgradePath);                                                                  

4520              }                                                                                                     
4521          };                                                                                                        
4522          if (waitUntilResume(r)) {                                                                                 
4523              return;                                                                                               
4524          }                                                                                                         
4525          if (mSavedState != null) {                                                                                
4526              if (!mWorkspace.hasFocus()) {                                                                         
4527                  mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();                                
4528              }                                                                                                     
4529              mSavedState = null;                                                                                   
4530          }                                                                                                         
4531                                                                                                                    
4532          mWorkspace.restoreInstanceStateForRemainingPages();                                                       
4533                                                                                                                    
4534          setWorkspaceLoading(false);                                                                               
4535          sendLoadingCompleteBroadcastIfNecessary();                                                                
4536                                                                                                                    
4537          // If we received the result of any pending adds while the loader was running (e.g. the                   
4538          // widget configuration forced an orientation change), process them now.                                  
4539          if (sPendingAddItem != null) {                                                                            
4540              final long screenId = completeAdd(sPendingAddItem);                                                   
4541                                                                                                                    
4542              // TODO: this moves the user to the page where the pending item was added. Ideally,                   
4543              // the screen would be guaranteed to exist after bind, and the page would be set through              
4544              // the workspace restore process.                                                                     
4545              mWorkspace.post(new Runnable() {                                                                      
4546                  @Override                                                                                         
4547                  public void run() {                                                                               
4548                      mWorkspace.snapToScreenId(screenId);                                                          
4549                  }                                                                                                 
4550              });                                                                                                   
4551              sPendingAddItem = null;                                                                               
4552          }                                                                                                         
4553                                                                                                                    
4554          if (upgradePath) {                                                                                        
4555              mWorkspace.getUniqueComponents(true, null);                                                           
4556              mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);                      
4557          }                                                                                                         
4558          PackageInstallerCompat.getInstance(this).onFinishBind();                                                  
4559                                                                                                                    
4560          if (mLauncherCallbacks != null) {                                                                         
4561              mLauncherCallbacks.finishBindingItems(upgradePath);                                                   

4562          }                                                                                                         
4563      }                                                                                                             
4564                                                                                                                    
4565      private void sendLoadingCompleteBroadcastIfNecessary() {                                                      
4566          if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {                                               
4567              String permission =                                                                                   
4568                      getResources().getString(R.string.receive_first_load_broadcast_permission);                   
4569              Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);                                               
4570              sendBroadcast(intent, permission);                                                                    
4571              SharedPreferences.Editor editor = mSharedPrefs.edit();                                                
4572              editor.putBoolean(FIRST_LOAD_COMPLETE, true);                                                         
4573              editor.apply();                                                                                       
4574          }                                                                                                         
4575      }                                                                                                             
4576                                                                                                                    
4577      public boolean isAllAppsButtonRank(int rank) {                                                                
4578          if (mHotseat != null) {                                                                                   
4579              return mHotseat.isAllAppsButtonRank(rank);                                                            
4580          }                                                                                                         
4581          return false;                                                                                             
4582      }                                                                                                             
4583                                                                                                                    
4584      private boolean canRunNewAppsAnimation() {                                                                    
4585          long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();                          
4586          return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);                                       
4587      }                                                                                                             
4588                                                                                                                    
4589      private ValueAnimator createNewAppBounceAnimation(View v, int i) {                                            
4590          ValueAnimator bounceAnim = LauncherAnimUtils.ofPropertyValuesHolder(v,                                    
4591                  PropertyValuesHolder.ofFloat("alpha", 1f),                                                        
4592                  PropertyValuesHolder.ofFloat("scaleX", 1f),                                                       
4593                  PropertyValuesHolder.ofFloat("scaleY", 1f));                                                      
4594          bounceAnim.setDuration(InstallShortcutReceiver.NEW_SHORTCUT_BOUNCE_DURATION);                             
4595          bounceAnim.setStartDelay(i * InstallShortcutReceiver.NEW_SHORTCUT_STAGGER_DELAY);                         
4596          bounceAnim.setInterpolator(new SmoothPagedView.OvershootInterpolator());                                  
4597          return bounceAnim;                                                                                        
4598      }                                                                                                             
4599                                                                                                                    
4600      public boolean useVerticalBarLayout() {                                                                       
4601          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4602                  getDeviceProfile().isVerticalBarLayout();                                                         
4603      }                                                                                                             
4604                                                                                                                    
4605      protected Rect getSearchBarBounds() {                                                                         
4606          return LauncherAppState.getInstance().getDynamicGrid().                                                   
4607                  getDeviceProfile().getSearchBarBounds();                                                          
4608      }                                                                                                             
4609                                                                                                                    
4610      public void bindSearchablesChanged() {                                                                        
4611          if (mSearchDropTargetBar == null) {                                                                       
4612              return;                                                                                               
4613          }                                                                                                         
4614          if (mQsb != null) {                                                                                       
4615              mSearchDropTargetBar.removeView(mQsb);                                                                
4616              mQsb = null;                                                                                          
4617          }                                                                                                         
4618          mSearchDropTargetBar.setQsbSearchBar(getQsbBar());                                                        

4619      }                                                                                                             
4620                                                                                                                    
4621      /**                                                                                                           
4622       * Add the icons for all apps.                                                                                
4623       *                                                                                                            
4624       * Implementation of the method from LauncherModel.Callbacks.                                                 
4625       */                                                                                                           
4626      public void bindAllApplications(final ArrayList<AppInfo> apps) {                                              
4627          if (LauncherAppState.isDisableAllApps()) {                                                                
4628              if (mIntentsOnWorkspaceFromUpgradePath != null) {                                                     
4629                  if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {                                                 
4630                      getHotseat().addAllAppsFolder(mIconCache, apps,                                               
4631                              mIntentsOnWorkspaceFromUpgradePath, Launcher.this, mWorkspace);                       
4632                  }                                                                                                 
4633                  mIntentsOnWorkspaceFromUpgradePath = null;                                                        
4634              }                                                                                                     
4635              if (mAppsCustomizeContent != null) {                                                                  
4636                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4637                          LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
4638              }                                                                                                     
4639          } else {                                                                                                  
4640              if (mAppsCustomizeContent != null) {                                                                  
4641                  mAppsCustomizeContent.setApps(apps);                                                              
4642                  mAppsCustomizeContent.onPackagesUpdated(                                                          
4643                          LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));                   
4644              }                                                                                                     






4645          }                                                                                                         
4646          if (mLauncherCallbacks != null) {                                                                         
4647              mLauncherCallbacks.bindAllApplications(apps);                                                         
4648          }                                                                                                         
4649      }                                                                                                             
4650                                                                                                                    
4651      /**                                                                                                           
4652       * A package was updated.                                                                                     
4653       *                                                                                                            
4654       * Implementation of the method from LauncherModel.Callbacks.                                                 
4655       */                                                                                                           
4656      public void bindAppsUpdated(final ArrayList<AppInfo> apps) {                                                  
4657          Runnable r = new Runnable() {                                                                             
4658              public void run() {                                                                                   
4659                  bindAppsUpdated(apps);                                                                            
4660              }                                                                                                     
4661          };                                                                                                        
4662          if (waitUntilResume(r)) {                                                                                 
4663              return;                                                                                               
4664          }                                                                                                         
4665                                                                                                                    
4666          if (!LauncherAppState.isDisableAllApps() &&                                                               
4667                  mAppsCustomizeContent != null) {                                                                  
4668              mAppsCustomizeContent.updateApps(apps);                                                               


4669          }                                                                                                         
4670      }                                                                                                             
4671                                                                                                                    
4672      @Override                                                                                                     
4673      public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {                             
4674          Runnable r = new Runnable() {                                                                             
4675              public void run() {                                                                                   
4676                  bindWidgetsRestored(widgets);                                                                     
4677              }                                                                                                     
4678          };                                                                                                        
4679          if (waitUntilResume(r)) {                                                                                 
4680              return;                                                                                               
4681          }                                                                                                         
4682          mWorkspace.widgetsRestored(widgets);                                                                      
4683      }                                                                                                             
4684                                                                                                                    
4685      /**                                                                                                           
4686       * Some shortcuts were updated in the background.                                                             
4687       *                                                                                                            
4688       * Implementation of the method from LauncherModel.Callbacks.                                                 
4689       */                                                                                                           
4690      @Override                                                                                                     
4691      public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,                                       
4692              final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {                                 
4693          Runnable r = new Runnable() {                                                                             
4694              public void run() {                                                                                   
4695                  bindShortcutsChanged(updated, removed, user);                                                     
4696              }                                                                                                     
4697          };                                                                                                        
4698          if (waitUntilResume(r)) {                                                                                 
4699              return;                                                                                               
4700          }                                                                                                         
4701                                                                                                                    
4702          if (!updated.isEmpty()) {                                                                                 
4703              mWorkspace.updateShortcuts(updated);                                                                  
4704          }                                                                                                         
4705                                                                                                                    
4706          if (!removed.isEmpty()) {                                                                                 
4707              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
4708              for (ShortcutInfo si : removed) {                                                                     
4709                  removedComponents.add(si.getTargetComponent());                                                   
4710              }                                                                                                     
4711              mWorkspace.removeItemsByComponentName(removedComponents, user);                                       
4712              // Notify the drag controller                                                                         
4713              mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);                            
4714          }                                                                                                         
4715      }                                                                                                             
4716                                                                                                                    
4717      /**                                                                                                           
4718       * Update the state of a package, typically related to install state.                                         
4719       *                                                                                                            
4720       * Implementation of the method from LauncherModel.Callbacks.                                                 
4721       */                                                                                                           
4722      @Override                                                                                                     
4723      public void updatePackageState(ArrayList<PackageInstallInfo> installInfo) {                                   
4724          if (mWorkspace != null) {                                                                                 
4725              mWorkspace.updatePackageState(installInfo);                                                           
4726          }                                                                                                         
4727      }                                                                                                             
4728                                                                                                                    
4729      /**                                                                                                           
4730       * Update the label and icon of all the icons in a package                                                    
4731       *                                                                                                            
4732       * Implementation of the method from LauncherModel.Callbacks.                                                 
4733       */                                                                                                           
4734      @Override                                                                                                     
4735      public void updatePackageBadge(String packageName) {                                                          
4736          if (mWorkspace != null) {                                                                                 
4737              mWorkspace.updatePackageBadge(packageName, UserHandleCompat.myUserHandle());                          
4738          }                                                                                                         
4739      }                                                                                                             
4740                                                                                                                    
4741      /**                                                                                                           
4742       * A package was uninstalled.  We take both the super set of packageNames                                     
4743       * in addition to specific applications to remove, the reason being that                                      
4744       * this can be called when a package is updated as well.  In that scenario,                                   
4745       * we only remove specific components from the workspace, where as                                            
4746       * package-removal should clear all items by package name.                                                    
4747       *                                                                                                            
4748       * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.               
4749       * Implementation of the method from LauncherModel.Callbacks.                                                 
4750       */                                                                                                           
4751      @Override                                                                                                     
4752      public void bindComponentsRemoved(final ArrayList<String> packageNames,                                       
4753              final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {                   
4754          Runnable r = new Runnable() {                                                                             
4755              public void run() {                                                                                   
4756                  bindComponentsRemoved(packageNames, appInfos, user, reason);                                      
4757              }                                                                                                     
4758          };                                                                                                        
4759          if (waitUntilResume(r)) {                                                                                 
4760              return;                                                                                               
4761          }                                                                                                         
4762                                                                                                                    
4763          if (reason == 0) {                                                                                        
4764              HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();                              
4765              for (AppInfo info : appInfos) {                                                                       
4766                  removedComponents.add(info.componentName);                                                        
4767              }                                                                                                     
4768              if (!packageNames.isEmpty()) {                                                                        
4769                  mWorkspace.removeItemsByPackageName(packageNames, user);                                          
4770              }                                                                                                     
4771              if (!removedComponents.isEmpty()) {                                                                   
4772                  mWorkspace.removeItemsByComponentName(removedComponents, user);                                   
4773              }                                                                                                     
4774              // Notify the drag controller                                                                         
4775              mDragController.onAppsRemoved(packageNames, removedComponents);                                       
4776                                                                                                                    
4777          } else {                                                                                                  
4778              mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);                                 
4779          }                                                                                                         
4780                                                                                                                    
4781          // Update AllApps                                                                                         
4782          if (!LauncherAppState.isDisableAllApps() &&                                                               
4783                  mAppsCustomizeContent != null) {                                                                  
4784              mAppsCustomizeContent.removeApps(appInfos);                                                           


4785          }                                                                                                         
4786      }                                                                                                             
4787                                                                                                                    
4788      /**                                                                                                           
4789       * A number of packages were updated.                                                                         
4790       */                                                                                                           
4791      private ArrayList<Object> mWidgetsAndShortcuts;                                                               

4792      private Runnable mBindPackagesUpdatedRunnable = new Runnable() {                                              
4793              public void run() {                                                                                   
4794                  bindPackagesUpdated(mWidgetsAndShortcuts);                                                        
4795                  mWidgetsAndShortcuts = null;                                                                      
4796              }                                                                                                     
4797          };                                                                                                        

4798      public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {                                
4799          if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {                                                
4800              mWidgetsAndShortcuts = widgetsAndShortcuts;                                                           
4801              return;                                                                                               
4802          }                                                                                                         
4803                                                                                                                    
4804          // Update the widgets pane                                                                                
4805          if (mAppsCustomizeContent != null) {                                                                      
4806              mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);                                         



4807          }                                                                                                         
4808      }                                                                                                             
4809                                                                                                                    
4810      private int mapConfigurationOriActivityInfoOri(int configOri) {                                               
4811          final Display d = getWindowManager().getDefaultDisplay();                                                 
4812          int naturalOri = Configuration.ORIENTATION_LANDSCAPE;                                                     
4813          switch (d.getRotation()) {                                                                                
4814          case Surface.ROTATION_0:                                                                                  
4815          case Surface.ROTATION_180:                                                                                
4816              // We are currently in the same basic orientation as the natural orientation                          
4817              naturalOri = configOri;                                                                               
4818              break;                                                                                                
4819          case Surface.ROTATION_90:                                                                                 
4820          case Surface.ROTATION_270:                                                                                
4821              // We are currently in the other basic orientation to the natural orientation                         
4822              naturalOri = (configOri == Configuration.ORIENTATION_LANDSCAPE) ?                                     
4823                      Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;                     
4824              break;                                                                                                
4825          }                                                                                                         
4826                                                                                                                    
4827          int[] oriMap = {                                                                                          
4828                  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,                                                         
4829                  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,                                                        
4830                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT,                                                 
4831                  ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE                                                 
4832          };                                                                                                        
4833          // Since the map starts at portrait, we need to offset if this device's natural orientation               
4834          // is landscape.                                                                                          
4835          int indexOffset = 0;                                                                                      
4836          if (naturalOri == Configuration.ORIENTATION_LANDSCAPE) {                                                  
4837              indexOffset = 1;                                                                                      
4838          }                                                                                                         
4839          return oriMap[(d.getRotation() + indexOffset) % 4];                                                       
4840      }                                                                                                             
4841                                                                                                                    
4842      public void lockScreenOrientation() {                                                                         
4843          if (Utilities.isRotationEnabled(this)) {                                                                  
4844              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {                                     
4845                  setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()                         
4846                          .getConfiguration().orientation));                                                        
4847              } else {                                                                                              
4848                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);                                  
4849              }                                                                                                     
4850          }                                                                                                         
4851      }                                                                                                             
4852      public void unlockScreenOrientation(boolean immediate) {                                                      
4853          if (Utilities.isRotationEnabled(this)) {                                                                  
4854              if (immediate) {                                                                                      
4855                  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                             
4856              } else {                                                                                              
4857                  mHandler.postDelayed(new Runnable() {                                                             
4858                      public void run() {                                                                           
4859                          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);                     
4860                      }                                                                                             
4861                  }, mRestoreScreenOrientationDelay);                                                               
4862              }                                                                                                     
4863          }                                                                                                         
4864      }                                                                                                             
4865                                                                                                                    
4866      protected boolean isLauncherPreinstalled() {                                                                  
4867          if (mLauncherCallbacks != null) {                                                                         
4868              return mLauncherCallbacks.isLauncherPreinstalled();                                                   
4869          }                                                                                                         
4870          PackageManager pm = getPackageManager();                                                                  
4871          try {                                                                                                     
4872              ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);                   
4873              if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {                                                  
4874                  return true;                                                                                      
4875              } else {                                                                                              
4876                  return false;                                                                                     
4877              }                                                                                                     
4878          } catch (NameNotFoundException e) {                                                                       
4879              e.printStackTrace();                                                                                  
4880              return false;                                                                                         
4881          }                                                                                                         
4882      }                                                                                                             
4883                                                                                                                    
4884      /**                                                                                                           
4885       * This method indicates whether or not we should suggest default wallpaper dimensions                        
4886       * when our wallpaper cropper was not yet used to set a wallpaper.                                            
4887       */                                                                                                           
4888      protected boolean overrideWallpaperDimensions() {                                                             
4889          if (mLauncherCallbacks != null) {                                                                         
4890              return mLauncherCallbacks.overrideWallpaperDimensions();                                              
4891          }                                                                                                         
4892          return true;                                                                                              
4893      }                                                                                                             
4894                                                                                                                    
4895      /**                                                                                                           
4896       * To be overridden by subclasses to indicate that there is an activity to launch                             
4897       * before showing the standard launcher experience.                                                           
4898       */                                                                                                           
4899      protected boolean hasFirstRunActivity() {                                                                     
4900          if (mLauncherCallbacks != null) {                                                                         
4901              return mLauncherCallbacks.hasFirstRunActivity();                                                      
4902          }                                                                                                         
4903          return false;                                                                                             
4904      }                                                                                                             
4905                                                                                                                    
4906      /**                                                                                                           
4907       * To be overridden by subclasses to launch any first run activity                                            
4908       */                                                                                                           
4909      protected Intent getFirstRunActivity() {                                                                      
4910          if (mLauncherCallbacks != null) {                                                                         
4911              return mLauncherCallbacks.getFirstRunActivity();                                                      
4912          }                                                                                                         
4913          return null;                                                                                              











4914      }                                                                                                             
4915                                                                                                                    
4916      private boolean shouldRunFirstRunActivity() {                                                                 
4917          return !ActivityManager.isRunningInTestHarness() &&                                                       
4918                  !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                    
4919      }                                                                                                             
4920                                                                                                                    
4921      protected boolean hasRunFirstRunActivity() {                                                                  
4922          return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);                                      
4923      }                                                                                                             
4924                                                                                                                    
4925      public boolean showFirstRunActivity() {                                                                       
4926          if (shouldRunFirstRunActivity() &&                                                                        
4927                  hasFirstRunActivity()) {                                                                          
4928              Intent firstRunIntent = getFirstRunActivity();                                                        
4929              if (firstRunIntent != null) {                                                                         
4930                  startActivity(firstRunIntent);                                                                    
4931                  markFirstRunActivityShown();                                                                      
4932                  return true;                                                                                      
4933              }                                                                                                     
4934          }                                                                                                         
4935          return false;                                                                                             
4936      }                                                                                                             
4937                                                                                                                    
4938      private void markFirstRunActivityShown() {                                                                    
4939          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
4940          editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);                                                    
4941          editor.apply();                                                                                           
4942      }                                                                                                             
4943                                                                                                                    
4944      /**                                                                                                           
4945       * To be overridden by subclasses to indicate that there is an in-activity full-screen intro                  
4946       * screen that must be displayed and dismissed.                                                               
4947       */                                                                                                           
4948      protected boolean hasDismissableIntroScreen() {                                                               
4949          if (mLauncherCallbacks != null) {                                                                         
4950              return mLauncherCallbacks.hasDismissableIntroScreen();                                                
4951          }                                                                                                         
4952          return false;                                                                                             
4953      }                                                                                                             
4954                                                                                                                    
4955      /**                                                                                                           
4956       * Full screen intro screen to be shown and dismissed before the launcher can be used.                        
4957       */                                                                                                           
4958      protected View getIntroScreen() {                                                                             
4959          if (mLauncherCallbacks != null) {                                                                         
4960              return mLauncherCallbacks.getIntroScreen();                                                           
4961          }                                                                                                         
4962          return null;                                                                                              
4963      }                                                                                                             
4964                                                                                                                    
4965      /**                                                                                                           
4966       * To be overriden by subclasses to indicate whether the in-activity intro screen has been                    
4967       * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.                             
4968       */                                                                                                           
4969      private boolean shouldShowIntroScreen() {                                                                     
4970          return hasDismissableIntroScreen() &&                                                                     
4971                  !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);                                          
4972      }                                                                                                             
4973                                                                                                                    
4974      protected void showIntroScreen() {                                                                            
4975          View introScreen = getIntroScreen();                                                                      
4976          changeWallpaperVisiblity(false);                                                                          
4977          if (introScreen != null) {                                                                                
4978              mDragLayer.showOverlayView(introScreen);                                                              
4979          }                                                                                                         
4980          if (mLauncherOverlayContainer != null) {                                                                  
4981              mLauncherOverlayContainer.setVisibility(View.INVISIBLE);                                              
4982          }                                                                                                         
4983      }                                                                                                             
4984                                                                                                                    
4985      public void dismissIntroScreen() {                                                                            
4986          markIntroScreenDismissed();                                                                               
4987          if (showFirstRunActivity()) {                                                                             
4988              // We delay hiding the intro view until the first run activity is showing. This                       
4989              // avoids a blip.                                                                                     
4990              mWorkspace.postDelayed(new Runnable() {                                                               
4991                  @Override                                                                                         
4992                  public void run() {                                                                               
4993                      mDragLayer.dismissOverlayView();                                                              
4994                      if (mLauncherOverlayContainer != null) {                                                      
4995                          mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                    
4996                      }                                                                                             
4997                      showFirstRunClings();                                                                         
4998                  }                                                                                                 
4999              }, ACTIVITY_START_DELAY);                                                                             
5000          } else {                                                                                                  
5001              mDragLayer.dismissOverlayView();                                                                      
5002              if (mLauncherOverlayContainer != null) {                                                              
5003                  mLauncherOverlayContainer.setVisibility(View.VISIBLE);                                            
5004              }                                                                                                     
5005              showFirstRunClings();                                                                                 
5006          }                                                                                                         
5007          changeWallpaperVisiblity(true);                                                                           
5008      }                                                                                                             
5009                                                                                                                    
5010      private void markIntroScreenDismissed() {                                                                     
5011          SharedPreferences.Editor editor = mSharedPrefs.edit();                                                    
5012          editor.putBoolean(INTRO_SCREEN_DISMISSED, true);                                                          
5013          editor.apply();                                                                                           
5014      }                                                                                                             
5015                                                                                                                    
5016      private void showFirstRunClings() {                                                                           

5017          // The two first run cling paths are mutually exclusive, if the launcher is preinstalled                  
5018          // on the device, then we always show the first run cling experience (or if there is no                   
5019          // launcher2). Otherwise, we prompt the user upon started for migration                                   
5020          LauncherClings launcherClings = new LauncherClings(this);                                                 
5021          if (launcherClings.shouldShowFirstRunOrMigrationClings()) {                                               
5022              if (mModel.canMigrateFromOldLauncherDb(this)) {                                                       
5023                  launcherClings.showMigrationCling();                                                              
5024              } else {                                                                                              
5025                  launcherClings.showLongPressCling(true);                                                          
5026              }                                                                                                     
5027          }                                                                                                         
5028      }                                                                                                             
5029                                                                                                                    
5030      void showWorkspaceSearchAndHotseat() {                                                                        
5031          if (mWorkspace != null) mWorkspace.setAlpha(1f);                                                          
5032          if (mHotseat != null) mHotseat.setAlpha(1f);                                                              
5033          if (mPageIndicators != null) mPageIndicators.setAlpha(1f);                                                
5034          if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);                              
5035      }                                                                                                             
5036                                                                                                                    
5037      void hideWorkspaceSearchAndHotseat() {                                                                        
5038          if (mWorkspace != null) mWorkspace.setAlpha(0f);                                                          
5039          if (mHotseat != null) mHotseat.setAlpha(0f);                                                              
5040          if (mPageIndicators != null) mPageIndicators.setAlpha(0f);                                                
5041          if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);                              
5042      }                                                                                                             
5043                                                                                                                    
5044      public ItemInfo createAppDragInfo(Intent appLaunchIntent) {                                                   
5045          // Called from search suggestion, not supported in other profiles.                                        
5046          final UserHandleCompat myUser = UserHandleCompat.myUserHandle();                                          
5047          LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);                                   
5048          LauncherActivityInfoCompat activityInfo = launcherApps.resolveActivity(appLaunchIntent,                   
5049                  myUser);                                                                                          
5050          if (activityInfo == null) {                                                                               
5051              return null;                                                                                          
5052          }                                                                                                         
5053          return new AppInfo(this, activityInfo, myUser, mIconCache, null);                                         

5054      }                                                                                                             
5055                                                                                                                    
5056      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5057              Bitmap icon) {                                                                                        
5058          // Called from search suggestion, not supported in other profiles.                                        
5059          return createShortcutDragInfo(shortcutIntent, caption, icon,                                              
5060                  UserHandleCompat.myUserHandle());                                                                 
5061      }                                                                                                             
5062                                                                                                                    
5063      public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,                           
5064              Bitmap icon, UserHandleCompat user) {                                                                 
5065          UserManagerCompat userManager = UserManagerCompat.getInstance(this);                                      
5066          CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);                       
5067          return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);                         
5068      }                                                                                                             
5069                                                                                                                    
5070      protected void moveWorkspaceToDefaultScreen() {                                                               
5071          mWorkspace.moveToDefaultScreen(false);                                                                    
5072      }                                                                                                             
5073                                                                                                                    
5074      public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {                                  
5075          dragView.setTag(dragInfo);                                                                                
5076          mWorkspace.onExternalDragStartedWithItem(dragView);                                                       
5077          mWorkspace.beginExternalDragShared(dragView, source);                                                     
5078      }                                                                                                             
5079                                                                                                                    
5080      @Override                                                                                                     
5081      public void onPageSwitch(View newPage, int newPageIndex) {                                                    
5082          if (mLauncherCallbacks != null) {                                                                         
5083              mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);                                               
5084          }                                                                                                         
5085      }                                                                                                             
5086                                                                                                                    
5087      /**                                                                                                           
5088       * Prints out out state for debugging.                                                                        
5089       */                                                                                                           
5090      public void dumpState() {                                                                                     
5091          Log.d(TAG, "BEGIN launcher3 dump state for launcher " + this);                                            
5092          Log.d(TAG, "mSavedState=" + mSavedState);                                                                 
5093          Log.d(TAG, "mWorkspaceLoading=" + mWorkspaceLoading);                                                     
5094          Log.d(TAG, "mRestoring=" + mRestoring);                                                                   
5095          Log.d(TAG, "mWaitingForResult=" + mWaitingForResult);                                                     
5096          Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);                                                 
5097          Log.d(TAG, "sFolders.size=" + sFolders.size());                                                           
5098          mModel.dumpState();                                                                                       
5099                                                                                                                    
5100          if (mAppsCustomizeContent != null) {                                                                      
5101              mAppsCustomizeContent.dumpState();                                                                    
5102          }                                                                                                         


5103          Log.d(TAG, "END launcher3 dump state");                                                                   
5104      }                                                                                                             
5105                                                                                                                    
5106      @Override                                                                                                     
5107      public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {                       
5108          super.dump(prefix, fd, writer, args);                                                                     
5109          synchronized (sDumpLogs) {                                                                                
5110              writer.println(" ");                                                                                  
5111              writer.println("Debug logs: ");                                                                       
5112              for (int i = 0; i < sDumpLogs.size(); i++) {                                                          
5113                  writer.println("  " + sDumpLogs.get(i));                                                          
5114              }                                                                                                     
5115          }                                                                                                         
5116          if (mLauncherCallbacks != null) {                                                                         
5117              mLauncherCallbacks.dump(prefix, fd, writer, args);                                                    
5118          }                                                                                                         
5119      }                                                                                                             
5120                                                                                                                    
5121      public static void dumpDebugLogsToConsole() {                                                                 
5122          if (DEBUG_DUMP_LOG) {                                                                                     
5123              synchronized (sDumpLogs) {                                                                            
5124                  Log.d(TAG, "");                                                                                   
5125                  Log.d(TAG, "*********************");                                                              
5126                  Log.d(TAG, "Launcher debug logs: ");                                                              
5127                  for (int i = 0; i < sDumpLogs.size(); i++) {                                                      
5128                      Log.d(TAG, "  " + sDumpLogs.get(i));                                                          
5129                  }                                                                                                 
5130                  Log.d(TAG, "*********************");                                                              
5131                  Log.d(TAG, "");                                                                                   
5132              }                                                                                                     
5133          }                                                                                                         
5134      }                                                                                                             
5135                                                                                                                    
5136      public static void addDumpLog(String tag, String log, boolean debugLog) {                                     
5137          addDumpLog(tag, log, null, debugLog);                                                                     
5138      }                                                                                                             
5139                                                                                                                    
5140      public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {                        
5141          if (debugLog) {                                                                                           
5142              if (e != null) {                                                                                      
5143                  Log.d(tag, log, e);                                                                               
5144              } else {                                                                                              
5145                  Log.d(tag, log);                                                                                  
5146              }                                                                                                     
5147          }                                                                                                         
5148          if (DEBUG_DUMP_LOG) {                                                                                     
5149              sDateStamp.setTime(System.currentTimeMillis());                                                       
5150              synchronized (sDumpLogs) {                                                                            
5151                  sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log                            
5152                      + (e == null ? "" : (", Exception: " + e)));                                                  
5153              }                                                                                                     
5154          }                                                                                                         
5155      }                                                                                                             
5156                                                                                                                    
5157      public static CustomAppWidget getCustomAppWidget(String name) {                                               
5158          return sCustomAppWidgets.get(name);                                                                       
5159      }                                                                                                             
5160                                                                                                                    
5161      public static HashMap<String, CustomAppWidget> getCustomAppWidgets() {                                        
5162          return sCustomAppWidgets;                                                                                 
5163      }                                                                                                             
5164                                                                                                                    
5165      public void dumpLogsToLocalData() {                                                                           
5166          if (DEBUG_DUMP_LOG) {                                                                                     
5167              new AsyncTask<Void, Void, Void>() {                                                                   
5168                  public Void doInBackground(Void ... args) {                                                       
5169                      boolean success = false;                                                                      
5170                      sDateStamp.setTime(sRunStart);                                                                
5171                      String FILENAME = sDateStamp.getMonth() + "-"                                                 
5172                              + sDateStamp.getDay() + "_"                                                           
5173                              + sDateStamp.getHours() + "-"                                                         
5174                              + sDateStamp.getMinutes() + "_"                                                       
5175                              + sDateStamp.getSeconds() + ".txt";                                                   
5176                                                                                                                    
5177                      FileOutputStream fos = null;                                                                  
5178                      File outFile = null;                                                                          
5179                      try {                                                                                         
5180                          outFile = new File(getFilesDir(), FILENAME);                                              
5181                          outFile.createNewFile();                                                                  
5182                          fos = new FileOutputStream(outFile);                                                      
5183                      } catch (Exception e) {                                                                       
5184                          e.printStackTrace();                                                                      
5185                      }                                                                                             
5186                      if (fos != null) {                                                                            
5187                          PrintWriter writer = new PrintWriter(fos);                                                
5188                                                                                                                    
5189                          writer.println(" ");                                                                      
5190                          writer.println("Debug logs: ");                                                           
5191                          synchronized (sDumpLogs) {                                                                
5192                              for (int i = 0; i < sDumpLogs.size(); i++) {                                          
5193                                  writer.println("  " + sDumpLogs.get(i));                                          
5194                              }                                                                                     
5195                          }                                                                                         
5196                          writer.close();                                                                           
5197                      }                                                                                             
5198                      try {                                                                                         
5199                          if (fos != null) {                                                                        
5200                              fos.close();                                                                          
5201                              success = true;                                                                       
5202                          }                                                                                         
5203                      } catch (IOException e) {                                                                     
5204                          e.printStackTrace();                                                                      
5205                      }                                                                                             
5206                      return null;                                                                                  
5207                  }                                                                                                 
5208              }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);                                     
5209          }                                                                                                         
5210      }                                                                                                             
5211  }                                                                                                                 
5212                                                                                                                    
5213  interface LauncherTransitionable {                                                                                
5214      View getContent();                                                                                            
5215      void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace);                          
5216      void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace);                            
5217      void onLauncherTransitionStep(Launcher l, float t);                                                           
5218      void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);                              
5219  }                                                                                                                 
5220                                                                                                                    
5221  interface DebugIntents {                                                                                          
5222      static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";                         
5223      static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";                       
5224  }